Android生命周期中的onPause()和onStop()

分類:IT技術 時間:2016-10-09

我不知道大家有沒有這樣問題,項目做多了,就容易忽略最最基礎的知識,其實我也是在最近發現了自己也存在這樣的問題。因此打算做一些最基礎的知識的調研來重新學習和回顧這些容易被忽略的知識。在這篇文章中,我打算針對android的生命周期為題,重新介紹一下onPause()和onStop()這兩個方法在一個Activity中的調用情況。

onPause()的定義

從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;
    }

onStop()的定義

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()方法是成對出現的。





Tags: Android background activity anything created

文章來源:


ads
ads

相關文章
ads

相關文章

ad