我不知道大家有没有这样问题,项目做多了,就容易忽略最最基础的知识,其实我也是在最近发现了自己也存在这样的问题。因此打算做一些最基础的知识的调研来重新学习和回顾这些容易被忽略的知识。在这篇文章中,我打算针对Android的生命周期为题,重新介绍一下onPause()和onStop()这两个方法在一个Activity中的调用情况。
从Android的源码来看,我们可以看到Android是这样给出的关于onPause()的解释:
(1)当Activity进入后台并且该Activity并未被销毁时,该方法会被调用。
(2)在Activity A中启动Activity B,如果B的活动页面覆盖在Activity A上方时,那么Activity A则会调用onPause()。
(3)onPause()方法的对应方法是onResume。也即,如果一个Activity调用了onPause()不活动状态时,那么当Activity进入活动状态的时候必定会调用onResume()。
/** * Called as part of the activity lifecycle when an activity is going into * the background, but has not (yet) been killed. The counterpart to * {@link #onResume}. * * <p>When activity B is launched in front of activity A, this callback will * be invoked on A. B will not be created until A's {@link #onPause} returns, * so be sure to not do anything lengthy here. * @see #onResume * @see #onSaveInstanceState * @see #onStop */ @CallSuper protected void onPause() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this); getApplication().dispatchActivityPaused(this); mCalled = true; }
Android源码中关于onStop()方法是这样给出解释的:
(1)当前的Activity不再呈现给用户的时候,onStop()被调用。那么如果Activity的theme是Dialog呢?我们在下面了解。
(2)如果onStop()方法被调用之后,那么该Activity就处于挂起状态。那么在此时的情况下,要么唤醒它(onRestart()),要么销毁它(onDestroy())。
(3)在某些情况下,该方法可能不会被调用。比如,系统内存过低导致无法确保在onPause()方法在被调用之后该Activity继续保持着运行状态。
/** * Called when you are no longer visible to the user. You will next * receive either {@link #onRestart}, {@link #onDestroy}, or nothing, * depending on later user activity. * * <p>Note that this method may never be called, in low memory situations * where the system does not have enough memory to keep your activity's * process running after its {@link #onPause} method is called. * * <p><em>Derived classes must call through to the super class's * implementation of this method. If they do not, an exception will be * thrown.</em></p> * * @see #onRestart * @see #onResume * @see #onSaveInstanceState * @see #onDestroy */ @CallSuper protected void onStop() { if (DEBUG_LIFECYCLE) Slog.v(TAG, "onStop " + this); if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false); mActivityTransitionState.onStop(); getApplication().dispatchActivityStopped(this); mTranslucentCallback = null; mCalled = true; }
那么在了解了这两个方法在Android生命周期的意义之后,大家可以开始思考几个问题:
(1)Activity A启动了Activity B的时候,Activity A和Activity B的生命周期的运行的方法排序是什么?
(2)当处于Activity B时,点击返回键回到Activity A时,Activity A和Activity B的生命周期的运行的方法排序是什么?
(3)当处于Activity B时,按下锁屏按钮,Activity A和Activity B的生命周期方法排序是什么?
(4)如果设置Activity B的主题为Dialog风格的话,那么(1)(2)(3)的结果分别是什么?
基于这三个问题,我们可以通过创建工程通过代码编写来一一验证。
首先我们先设置Activity B为普通的Activity风格。在Activity A中启动Activity B之后,发现调用方法的排序如下:
onPause(A) -> onCreate(B) -> onStart(B) -> onResume(B) -> onStop(A)
此时,我们处于Activity B,这时我们点击返回按钮,发现生命周期中的方法排序如下:
onPause(B) -> onRestart(A) -> onStart(A) -> onResume(A) -> onStop(B) -> onDestroy(B)
那么如果我们现在处于Activity B,这时按下锁屏按钮之后,发现生命周期中的方法调用如下:
onPause(B) -> onStop(B)
重新唤醒屏幕时,我们能够得到如下结果:
onRestart(B) -> onStart(B) -> onResume(B)
之后,我们修改一下Activity B的主题风格为dialog看看在以上三个生命周期的排序中有什么变化。
<activity android:name=".SecondActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.Dialog" />
那么在第一个问题中,从Activity A进入Activity B我们得到的结果如下:
onPause(A) -> onCreate(B) -> onStart(B) -> onResume(B)
通过与之前的普通Activity B的主题方式比较,我们发现在打印的结果中少了onStop()方法,这时因为Activity B采用了Dialog的主题方式,Activity A对于用户依然可见,所以Activity A不会调用自己的onStop()方法。
此时,我们处于Activity B,并且Activity B覆盖在Activity A的上方,但是Activity依然可见。这时点击返回键,我们发现如下结果:
onPause(B) -> onResume(A) -> onStop(B) -> onDestroy(B)
通过与之前的普通Activity B的主题方式比较,由于Activity A不调用自己的onStop()方法,那么自然在Activity B销毁之后,Activity A将不会调用自己的onRestart()和onStart()方法。
那么如果在Activity B时,我们按下锁屏键,发现结果如下:
onPause(B) -> onStop(B) -> onStop(A)
通过与之前的普通Activity B的主题方式比较,由于Activity A对于用户可见,因此在锁屏时,自身会调用onStop()方法将自己挂起。
当我们重新唤醒屏幕时,我们将得到如下结果:onRestart(B) -> onStart(B) -> onRestart(A) -> onStart(A) -> onResume(B)
通过与之前的普通Activity B的主题方式比较,在重新唤醒屏幕之后,自然Activity A重新被唤醒时则会调用onRestart()和onStart()方法。
通过以上的代码运行结果,我们可以得到一下几点结论:
(1)当Activity A启动Activity B时,Activity A首先会将自己的状态变为不活动状态,也即调用onPause()。然后系统开始启动Activity B,并开始走Activity B的生命周期。在完成Activity B的生命周期之后,再将Activity A挂起,即调用Activity A的onStop()方法。
(2)onPause()和onResume()方法是成对出现的。
(3)onStop()方法和onRestart()方法是成对出现的。