GVKun编程网logo

在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?

13

如果您对在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在onPause,onS

如果您对在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?的详细内容,并且为您提供关于Android MVP-分离视图(onPause VS onDestroy)和状态保存、Android onCreate()、onStart()、onResume()、onDestory()、onStop()、onPause()什么时候执行、android – onPause()之前onStopped()在活动生命周期中、android – 为什么Camera需要在onPause()而不是onstop()方法中释放?的有价值信息。

本文目录一览:

在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?

在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?

我刚浏览了Android开发者网站,刷新了活动生命周期,在每个代码示例中,超类方法旁边都有一条注释,上面写着“始终先调用超类方法”。

尽管这在创建半周期(onCreate,onStart和onResume)中是有意义的,但对于销毁半周期的正确过程是什么,我还是有些困惑:onPause,onStop,onDestroy。

首先销毁实例专用资源,然后销毁实例专用资源可能依赖的超类资源,这是有道理的,而不是相反。我想念什么?

编辑 :由于人们似乎对这个问题的意图感到困惑,所以我想知道以下哪个是正确的? 为什么?

1,谷歌建议

    @Override    protected void onStop() {      super.onStop();  // Always call the superclass method first      //my implementation here    }

2.另一种方式

    @Override    protected void onStop() {       //my implementation here       super.onStop();      }

答案1

小编典典

首先销毁实例特定的资源,然后销毁实例特定资源可能依赖的超类资源是有道理的,而不是相反。但是这些评论暗示了另外的观点。 我想念什么?

我认为:没有一件事情。

Mark的这个答案(又名SO上的CommonsWare)阐明了这个问题:链接-
对超类方法的调用应该是第一个语句吗?。但是,您可以在他的答案中看到以下评论:

但是,为什么官方文档在onPause()中说:“总是先调用超类方法”?

回到原点。好吧,让我们从另一个角度来看这个。我们知道Java语言规范 没有
指定super.overridenMethod()必须放置调用的顺序(或者是否必须放置调用)。

如果是Activity类,super.overridenMethod()则必须 执行 调用:

if (!mCalled) {    throw new SuperNotCalledException(        "Activity " + mComponent.toShortString() +            " did not call through to super.onStop()");}

mCalled在中设置为true Activity.onStop()

现在,唯一需要讨论的细节是订购。

I also know that both work

当然。查看Activity.onPause()的方法主体:

protected void onPause() {    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);    // This is to invoke     // Application.ActivityLifecyleCallbacks.onActivityPaused(Activity)    getApplication().dispatchActivityPaused(this);    // The flag to enforce calling of this method    mCalled = true;}

无论采用哪种方式将呼叫夹在上super.onPause(),您都可以。Activity.onStop()具有相似的方法主体。但是看看Activity.onDestroy():

protected void onDestroy() {    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);    mCalled = true;    // dismiss any dialogs we are managing.    if (mManagedDialogs != null) {        final int numDialogs = mManagedDialogs.size();        for (int i = 0; i < numDialogs; i++) {            final ManagedDialog md = mManagedDialogs.valueAt(i);            if (md.mDialog.isShowing()) {                md.mDialog.dismiss();            }        }        mManagedDialogs = null;    }    // close any cursors we are managing.    synchronized (mManagedCursors) {        int numCursors = mManagedCursors.size();        for (int i = 0; i < numCursors; i++) {            ManagedCursor c = mManagedCursors.get(i);            if (c != null) {                c.mCursor.close();            }        }        mManagedCursors.clear();    }    // Close any open search dialog    if (mSearchManager != null) {        mSearchManager.stopSearch();    }    getApplication().dispatchActivityDestroyed(this);}

在这里,排序 可能 取决于您的活动设置方式以及调用是否super.onDestroy()会干扰后面的代码,可能 会很 重要。

最后,该声明Always call the superclass methodfirst似乎没有足够的证据来支持它。更糟糕的是(对于该语句)以下代码摘自android.app.ListActivity

public class ListActivity extends Activity {    ....    @Override    protected void onDestroy() {        mHandler.removeCallbacks(mRequestFocus);        super.onDestroy();    }    ....    }

并且,来自android sdk中包含的LunarLander示例应用程序:

public class LunarLander extends Activity {    ....    @Override    protected void onPause() {        mLunarView.getThread().pause(); // pause game when Activity pauses        super.onPause();    }    ....}

总结和值得一提:

用户Philip Sheard
:提供一种方案,super.onPause()在这种情况下,如果Activity开始使用,则必须延迟呼叫startActivityForResult(Intent)。使用setResult(...)
after 设置结果super.onPause()将不起作用。后来,他在对答案的评论中对此进行了澄清。

用户Sherif elKhatib :从逻辑上解释为什么让超类首先初始化其资源并最后破坏其资源的原因:

让我们考虑一下您下载的一个库,该库具有一个LocationActivity,其中包含提供位置的getLocation()函数。最有可能的是,
此活动将需要在onCreate()中初始化其内容,这将迫使您首先调用super.onCreate
。您已经这样做了,因为您认为这很有道理。现在,在您的onDestroy中,您决定要将该位置保存在SharedPreferences中的某个位置。如果首先调用super.onDestroy,则在一定程度上调用后getLocation将返回空值,因为LocationActivity的实现会使onDestroy中的位置值无效。这个想法是,如果发生这种情况,您不会怪它。
因此,在完成自己的onDestroy之后,您将在最后调用super.onDestroy。

他继续指出:如果子类与父类适当地隔离(就资源依赖而言),则super.X()调用不必遵循任何顺序规范。

在此页面上查看他的答案,以通读super.onDestroy()调用位置 确实 会影响程序逻辑的情况。

根据马克的回答

重写的方法是组件创建的一部分(onCreate(),onStart(),onResume()等),您应该作为第一条语句链接到超类
,以确保Android在您开始之前有机会做自己的工作尝试做一些依赖于已经完成的工作的事情。

重写的方法是组件破坏的一部分(onPause(),onStop(),onDestroy()等),您应该首先完成工作并最后链接到超类
。这样,如果Android清理了您的工作所依赖的内容,则您将首先完成工作。

返回除void以外的内容的方法(onCreateOptionsMenu()等),有时您会链接到return语句中的超类,假设您没有专门执行需要强制特定返回值的操作。

总体而言,其他一切(如onActivityResult())都取决于您。首先,我倾向于链接到超类,但是除非遇到问题,否则稍后链接应该没问题。

Bob Kerns 从这个话题:

这是一个很好的模式[(Mark在上面建议的模式)],但是我发现了一些例外。例如,
除非将主题放在超类的onCreate()之前,否则我想应用到PreferenceActivity的主题不会生效。

用户Steve Benett 也引起注意:

我只知道一种情况,需要超级调用的时间。 如果要更改主题或显示的标准行为,例如onCreate,则必须先调用super才能看到效果
。否则,AFAIK在您调用它的时间没有区别。

用户Sunil Mishra 确认调用Activity类的方法时,顺序(最有可能)不起作用。他还声称, 首先调用超类方法被认为是最佳实践
。但是,我不能证实这一点。

用户LOG_TAG :说明为什么对超类 构造函数 的调用必须先于其他所有。我认为,这种解释不会增加所要提出的问题。

结束语 :信任, 但请 验证。此页面上的大多数答案都采用这种方法来查看该语句Always call the superclass methodfirst是否具有逻辑依据。事实证明,事实并非如此。至少,不是在Activity类的情况下。通常,应该通读超类的源代码,以确定是否需要对超类的方法进行排序调用。

Android MVP-分离视图(onPause VS onDestroy)和状态保存

Android MVP-分离视图(onPause VS onDestroy)和状态保存

我正在尝试在我的应用程序中实现MVP架构.

但是,在阅读了一些博客并查看了一些示例项目示例之后,我不确定我是否完全了解分离视图的正确位置以及在异步操作后第二次附加视图后应该怎么做.

我看到的大多数示例都只是在异步调用后对视图的null验证检查进行了总结.

我将通过一个示例来阐明我的观点-通过电话号码登录/注册(主要思想是重要,而不是示例本身)

有一个显示片段的活动-LoginFragment.
用户输入他的电话号码并尝试登录.
如果用户退出-他应该导航到另一个活动(输入短信收到的代码后.)
如果用户没有退出,则应导航到注册过程-RegistrationFragment.
如果出现错误,则会出现一个带有错误消息的对话框,ErrorDialogFragment.

现在,用户按下登录按钮并等待该过程完成,一切顺利.

但是,在不那么开心的流程中(不是那么频繁,但绝对不能忽略),用户按下登录按钮,然后按下主页按钮,或者接听电话.

在方案1中,我们在onCreate / onDestroy中附加/分离视图,一旦异步登录操作完成,我们应该替换为RegistrationFragment或显示ErrorDialogFragment,就有机会遇到著名的IllegalStateException:
getting exception “IllegalStateException: Can not perform this action after onSaveInstanceState”

在方案2中,我们在onResume / onPause中附加/分离视图,一旦异步登录操作完成,由于视图已分离,我们将无法替换片段或显示对话框.

在这种情况下,我不确定该怎么做.
我们是否应该采用场景1并使用commitallowingstateloss提交事务?
恐怕这是个坏主意.

还是我们应该使用场景2.在这种情况下,当再次附加视图时,我们应该采取相应的措施,这意味着将状态(RegistrationRequied,ErrorHasOccured,LoginProcessstillRunning等)保存在Presenter / Interactor中.

有人可以对此有所启示吗?

提前致谢!

解决方法:

哦,Android生命周期的乐趣.我感到你很痛苦.

以我的个人经验,诉诸commitAllowingStateLoss通常是在后台更新Ui(视图)的症状(如您所述,UI可能会被破坏).

我的建议是,您不要在未检查活动是否已后台的情况下尝试更新ui(视情况而定,onStop或onPause).如果您的用户界面已经有背景,请记住您需要进行的更改,并在重新连接您的用户界面时进行(根据情况,选择onStart或onResume).

本质上,我是说您应该遵循方案2.是的.您将不得不以某种方式保存很多状态.

不幸的是,这并不容易,从使用事件总线一直到使用RxJava,有很多方法可以做到这一点.
每种方法都有其优点和缺点,它们实在太复杂了,无法在单个文章中进行详细讨论.

但是,我有一段博客文章是我前一段时间写的,它不需要额外的库就可以做到这一点.

现在有点过时了,但可能会给您一些想法:A Simple MVP aproach for Android

祝一切顺利.

亲切的问候,
克里斯.

Android onCreate()、onStart()、onResume()、onDestory()、onStop()、onPause()什么时候执行

Android onCreate()、onStart()、onResume()、onDestory()、onStop()、onPause()什么时候执行

一个Activity活动就是一个界面的布局。
程序正常启动时:onCreate()->onStart()->onResume();
onCreate()在活动第一次创建时被调用,主要用于加载布局
onStart()这个方法在活动由不可见变为可见的时候调用。
onResume这个方法在活动准备好和用户进行交互的时候调用。此时的活动一定位于返回栈的栈顶,并且处于运行状态.
三种调用的场景:
一个Activity启动另一个Activity: onPause()->onStop(),再返回:onRestart()->onStart()->onResume()
程序按back 退出: onPause()->onStop()->onDestory(),再进入:onCreate()->onStart()->onResume();
程序按home 退出: onPause()->onStop(),再进入:onRestart()->onStart()->onResume();

生命周期的一些细节:
1     Activity 第一次创建时会调用 onCreate(Bundle)。 该方法用于创建 Activity 的用户界面,创建所需的后台线程,并执行其他的全局初始化。如果能获得Activity以前的状态,就可以将包含此状态的 android.os.Bundle 对象传给onCreate();否则就传入一个空引用。在调用 onCreate(Bundle)之后,
Android 总会调用 onStart()。
2      在用户看到 Activity 之前会调用 onStart()方法。当 Activity 进入前台时, Android在调用 onStart()之后就会调用 onResume();当 Activity 变成隐藏状态时, Android就会在调用 onStart()之后调用 onStop()。
3      当 Activity 停止后,在其重新启动之前会调用 onRestart()。在调用 onRestart()之后,Android 会调用 onStart()。
4      在 Activity 开始跟用户交互之前会调用 onResume()。此时, Activity 获得了焦点,用户的输入会发送给该 Activity。当 Activity 必须暂停时,Android 就会在调用onResume()之后调用 onPause()。
5      当 Android 要恢复另一个 Activity 时会调用 onPause()。该方法一般用于保留未保存的修改,停止可能会消耗处理器资源的动画等。它应该很快地完成工作,因为只有等该方法返回时,下一个 Activity 才能被重新激活。在调用了 onPause()之后,当 Activity 开始跟用户交互时, Android 就会使用onResume(),当 Activity 变成隐藏状态时调用 onStop()。 许多 Activity 执行 onPause()方法来提交数据的改变或者准备停止与用户的交互操作。
6      当 Activity 变为隐藏状态时会调用 onStop()。这种情况可能发生在 Activity 被销毁,或者另一个 Activity(正在运行的或新启动的)被重新激活并将覆盖前一个 Activity时。在调用 onStop()之后,如果 Activity 重新跟用户交互, Android 会调用 onRestart()方法;
7     如果 Activity 退出了,就会调用 onDestroy()方法。
8      在 Activity 被销毁之前会调用 onDestroy(),除非是内存不够, Android 强行终止了Activity 的进程。在这种情况下就不会调用 onDestroy()。如果调用了 onDestroy(),那它就是该 Activity 接收的最终调用。在 onPause()、 onStop()或 onDestroy()返回之后, Android 可以终止托管 Activity 的进程。从 onPause()返回后到调用 onResume()之前, Activity 都处于可终止状态。在 onPause()再次返回之前, Activity 都不会再处于可终止状态。

android – onPause()之前onStopped()在活动生命周期中

android – onPause()之前onStopped()在活动生命周期中

在Andoid Acitivity生命周期中,为什么活动在进入onStopped()之前会经历onPause()?为什么国家不能直接进入onStopped()?

解决方法:

因为documentation这么说:-)

这是有道理的.应用程序已打开,用户按下主页按钮:onPause()被调用.一段时间后,系统需要内存并关闭应用程序:onStop()被调用.

android – 为什么Camera需要在onPause()而不是onstop()方法中释放?

android – 为什么Camera需要在onPause()而不是onstop()方法中释放?

我似乎错过了一些东西因为我无法理解为什么在 Android文档 (Android Camera doc. link)中建议在onPause()Activity回调中释放Camera对象(以及MediaRecorder)?到那时候Activity仍然可以看到,Camera可能正在运行预览,那么为什么Camera对象会在onPause()而不是onStop()中被释放?我知道MediaRecorder对象可以在onPause()中停止,但Camera本身对我没有意义.我在这里错过了什么? Android文档中的一段代码如下(在Releasing the Camera标题下):

@Override
protected void onPause() {
    super.onPause();
    releaseMediaRecorder();       // if you are using MediaRecorder,release it first
    releaseCamera();              // release the camera immediately on pause event
}

private void releaseMediaRecorder(){
    if (mMediaRecorder != null) {
        mMediaRecorder.reset();   // clear recorder configuration
        mMediaRecorder.release(); // release the recorder object
        mMediaRecorder = null;
        mCamera.lock();           // lock camera for later use
    }
}

解决方法

根据 application lifecycle

Paused
    Another activity is in the foreground and has focus,but this one is 
            still visible. That is,another activity is visible on top of this 
            one and that activity is partially transparent or doesn''t cover the 
            entire screen. (...)

我认为文档遵循拇指规则“尽快释放资源”:onPause早于onStop.

在用户必须注意弹出窗口时,背景窗口中的摄像头需要能量.

背景中的相机当然更舒适,但对于移动电池来说,续航时间更为重要.

拦截您活动的弹出窗口可能需要摄像头和/或可能需要大量内存.

在摄像机应在后台继续录制的情况下,摄像机的生命周期和录制应由服务控制

关于在onPause,onStop和onDestroy方法中调用超类方法的正确顺序是什么?为什么?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android MVP-分离视图(onPause VS onDestroy)和状态保存、Android onCreate()、onStart()、onResume()、onDestory()、onStop()、onPause()什么时候执行、android – onPause()之前onStopped()在活动生命周期中、android – 为什么Camera需要在onPause()而不是onstop()方法中释放?等相关知识的信息别忘了在本站进行查找喔。

本文标签: