全面解析Activity的生命周期
歡迎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的生命周期