1. 程式人生 > >全面解析Activity的生命周期

全面解析Activity的生命周期

body hub code uil style androidm ren lin lease

歡迎Follow我的GitHub, 關註我的CSDN.

在Android應用中, Activity是最重要的組件, 其生命周期(Lifecycle)被大家所熟知.
可是, 大家須要註意一些細節, 才幹在使用中得心應手.

Android的生命周期改變主要有兩種情況, 一是用戶參與Activity生命周期的改變, 二是系統回收或配置改動導致的改變.

本文演示樣例的GitHub下載地址

技術分享圖片

Android的生命周期:

技術分享圖片


1. 用戶參與

用戶最常見的兩種操作, 按Home鍵或Back鍵.
(1) 點擊Home鍵, 暫停當前Activity, 調用onPause -> onStop; 再次返回, 恢復當前頁面, 調用onRestart -> onStart -> onResume.
(2) 點擊Back鍵, 關閉當前Activity, 調用onPause -> onStop -> onDestroy; 再次啟動則為重建, 從onCreate開始調用.

onStart()是Activity可見, 無法交互; onResume()是Activity可見, 能夠交互. onPause是Activity無法交互, 必須運行前一個Activity的onPause完畢, 後一個Activity才幹啟動, 在onPause中, 不能運行復雜的操作, 否則會影響下一個Activity啟動速度. onStop是Activity關閉顯示.

註意: 啟動透明頁面僅僅調用onPause, 不會調用onStop, 即僅僅是不能夠交互, 但仍在前臺顯示. 啟動非透明頁, 會調用onPause -> onStop.

運行操作, 啟動透明頁, 關閉透明頁, 啟動非透明頁, 關閉非透明頁.

E/DEBUG-WCL: MainActivity: onPause
E/DEBUG-WCL: MainActivity: onSaveInstanceState
E/DEBUG-WCL: TranslateActivity: onPause
E/DEBUG-WCL: MainActivity: onResume
E/DEBUG-WCL: TranslateActivity: onStop
E/DEBUG-WCL: TranslateActivity: onDestroy
E/DEBUG-WCL: MainActivity: onPause
E/DEBUG-WCL: SecondActivity: onCreate
E/DEBUG-WCL: MainActivity: onSaveInstanceState E/DEBUG-WCL: MainActivity: onStop E/DEBUG-WCL: SecondActivity: onPause E/DEBUG-WCL: MainActivity: onRestart E/DEBUG-WCL: MainActivity: onStart E/DEBUG-WCL: MainActivity: onResume E/DEBUG-WCL: SecondActivity: onStop E/DEBUG-WCL: SecondActivity: onDestroy

註意透明頁啟動, 主頁僅僅會調用onPause, 而不調用onStop.
onSaveInstanceState方法, 在關閉時, 都會運行, 但非系統調用啟動, 不會運行恢復數據的操作, 即onRestoreInstanceState方法.


2. 系統重建

在系統配置發生改變時, Activity就會重建, 因為是系統控制的關閉和啟動, 會調用onSaveInstanceState保存數據, onRestoreInstanceState恢復數據.

E/DEBUG-WCL: MainActivity: onPause
E/DEBUG-WCL: MainActivity: onSaveInstanceState
E/DEBUG-WCL: MainActivity: onStop
E/DEBUG-WCL: MainActivity: onDestroy
E/DEBUG-WCL: MainActivity: onCreate
E/DEBUG-WCL: MainActivity: onStart
E/DEBUG-WCL: MainActivity: onRestoreInstanceState
E/DEBUG-WCL: MainActivity: onResume

onRestoreInstanceState在能夠交互之前(onResume)運行, onSaveInstanceState在停止交互(onPause)之後運行.

系統會保存關閉之前的視圖結構和暫存數據. 視圖詳細保存的數據項, 能夠通過閱讀文檔, 也能夠直接閱讀代碼. 搜索視圖類的onSaveInstanceState方法, 類SavedState就是保存的數據.

TextView的onSaveInstanceState

    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();

        // Save state if we are forced to
        boolean save = mFreezesText;
        int start = 0;
        int end = 0;

        if (mText != null) {
            start = getSelectionStart();
            end = getSelectionEnd();
            if (start >= 0 || end >= 0) {
                // Or save state if there is a selection
                save = true;
            }
        }

        if (save) {
            SavedState ss = new SavedState(superState);
            // XXX Should also save the current scroll position!
            ss.selStart = start;
            ss.selEnd = end;

            if (mText instanceof Spanned) {
                Spannable sp = new SpannableStringBuilder(mText);

                if (mEditor != null) {
                    removeMisspelledSpans(sp);
                    sp.removeSpan(mEditor.mSuggestionRangeSpan);
                }

                ss.text = sp;
            } else {
                ss.text = mText.toString();
            }

            if (isFocused() && start >= 0 && end >= 0) {
                ss.frozenWithFocus = true;
            }

            ss.error = getError();

            if (mEditor != null) {
                ss.editorState = mEditor.saveInstanceState();
            }
            return ss;
        }

        return superState;
    }

TextView主要保存了內容Text和焦點Focus, 另一些位置和錯誤信息.

假設是恢復自己定義數據, 恢復時機, 能夠選擇onCreate或onRestoreInstanceState, 差別是onCreate須要推斷savedInstanceState是否為空, 而onRestoreInstanceState的參數savedInstanceState是一定非空, 否則不會調用. 推薦使用onRestoreInstanceState.

onCreate判空

        if (savedInstanceState != null) {
            String txt = savedInstanceState.getString(EXTRA_TEXT);
            Log.e(TAG, "[onCreate]savedInstanceState: " + txt);
        }

在AndroidManifest的Activity屬性中加入

android:configChanges="orientation|screenSize"

防止在旋轉屏幕時, 重繪頁面, 但屏幕仍能夠旋轉.
不會調用生命周期, 而是調用onConfigurationChanged處理旋轉屏幕事件.

使用android:screenOrientation=”portrait”會使屏幕保持豎直, 無法旋轉.

動畫

技術分享圖片


參考

OK, that’s all! Enjoy it!

全面解析Activity的生命周期