Activity Lifecycle實驗:1 = Root Activity, 2 = Sub Activity started by 1
Scenario A
- 先測單一Activity時,程式啟動,進入主畫面
onCreate 1
onStart 1
onResume 1 - 按 BACK,螢幕跑回桌面
onPause 1
onStop 1
onDestroy 1 - 選程式icon再進入主畫面
onCreate 1
onStart 1
onResume 1
結論:在 Root 按 BACK 等於結束程式。
Scenario B
- 程式啟動進入主畫面
onCreate 1
onStart 1
onResume 1 - 按 HOME,螢幕跑回桌面
onSaveInstanceState 1
onPause 1
onStop 1 - 選程式icon再進入主畫面
onRestart 1
onStart 1
onResume 1
結論:在 Root 按 HOME 只是把程式放到背景,重新進入後不會執行 onCreate。
Scenario C
- 程式啟動進入主畫面
onCreate 1
onStart 1
onResume 1 - 按下按鈕,進入畫面2
onSaveInstanceState 1
onPause 1
onCreate 2
onStart 2
onResume 2
onStop 1 - 按BACK 返回主畫面
onPause 2
onRestart 1
onStart 1
onResume 1
onStop 2
onDestroy 2
結論:在 Sub 按 BACK,Sub活動會消滅,另外看起來Android滿仔細的,停掉2重開1的流程是有巧妙的安排。
Scenario D
- 程式啟動進入主畫面
onCreate 1
onStart 1
onResume 1 - 按下按鈕,進入畫面2
onSaveInstanceState 1
onPause 1
onCreate 2
onStart 2
onResume 2
onStop 1 - 在畫面2,按HOME 返回桌面
onSaveInstanceState 2
onPause 2
onStop 2 - 選程式icon,會直接進入畫面2
onRestart 2
onStart 2
onResume 2
結論:在 Sub活動按 HOME 會暫停Sub (Root早就暫停了),再回到程式是直接 Reactivate Sub畫面
Scenario E
- 補充:在 textbox 打字到一半,按POWER鎖住螢幕
onSaveInstanceState x
onPause x - 解除鎖定,會直接回app畫面,並且之前的輸入到一半的文字不會消失
onResume x
Scenario F
- 補充:打字到一半,有電話進來
onSaveInstanceState x
onPause x
onStop x - 掛斷電話,畫面及游標回到原來的 textbox,輸入的文字還在
onRestart x
onStart x
onResume x
這裡面有個更讓我在意的事情,就是我在兩個Activity都有overwrite onRestoreInstanceState,並加入message,但是從來都沒有被呼叫過。官方手冊在提到 onSaveInstance 的時候,也是說明這儲存的bundle是讓你在下次onCreate時使用,並沒有提到 onRestoreInstanceState。不論如何,這兩個method並不是在 Lifecycle 中必定會呼叫的程序,不要依賴它們來儲存使用者輸入到一半的資料,照設計目的看來比較像是記住上一次是看到第二頁之類的功能。之後如果有讀到相關說明再補充上來。
上面的實驗雖然 onPause 和 onStop 總是在一起,但根據手冊,Pause 狀態跟 Stop狀態確實是不同。Pause狀態下,使用者不能與這個活動互動,但是仍然看的見它。也就是說如果你產生了一個透明的或不占到全螢幕的子活動,則主活動有可能只會 Pause,而不會 Stop。而Pause狀態對系統來說仍然是alive,只有系統資源真的太低時才會kill它,而Stop的活動相對來說很有機會被殺掉。(不知道 Alert Dialog 與 Parent是不是這種關係)
關於保存狀態或傳遞資料方面,官方SDK手冊強調,如果需要回傳結果給主活動,不要在 onDestroy 加入 setResult function! ,之前被 google 到的某論壇文章騙了,說可以在 onDestroy setResult,怒。根據手冊說,想要做保存資料,例如 user 輸入之類的事情應該放在 onPause,onDestroy 應該只做釋放資源之類的動作,因為 oPause是唯一一個保證會在系統 kill process 之前呼叫並且等待其return的function。實際上測試的結果,確實在 onDestroy 試圖 setResult 是沒有用的,intent 應該是會隨著此sub Activity 被消滅,onActivityResult 的地方會得到 null intent。一般來說返回鍵表示要放棄現在的動作返回,不保留狀態還算合理,但看了一下Android的通訊錄app,按下返回鍵時,其實還是當作 submit 立刻儲存了打到一半的資料,這可能是為了防止編輯到一半電話進來,資料全被清空的滿腔怒火。另外已經在背景的Activity是有機會被kill process的。萬一發生了這事情,在kill process之前會先 onSaveInstanceState(Bundle),下次再 onCreate(Budle) 時就可以使用這 bundle 的動態暫存資料。
總之,儲存永久性資料的動作可以在 onPause做,onDestroy只能做資源回收,比如 connection close,之後有其他心得會再補充資料。
天阿!!娘子快來看神的分享!!!
謝謝神的分享