各個生命週期
- onCreate——表示Activity正在創建,是生命週期的第一個方法,我們可以在這個方法中做一些初始化工作。
- onRestart——表示Activity正在重新啓動,一般情況下,噹噹前的Activity從不可見變爲可見狀態時,onRestart就會被調用。這種行爲一般是用戶行爲所導致的,比如用戶點擊home鍵切換到桌面或者用戶打開了一個新的Activity,這時當前Activity就會暫停。也就是onPause和onStop執行了,接着用戶又回到了這個Activity,就會出現這種情況。
- onStart——表示Activity正在被啓動,即將開始,這時Activity已經可見了,但是還沒有出現在前臺,還無法和用戶交互。可以理解爲Activity已經顯示出來了,但是我們還看不到。
- onResume——表示Activity已經可見了,並且出現在前臺並開始活動。注意這個和onStart的區別:onStart和onResume都表示Activity已經可見,但是onStart的時候Activity還在後臺,onResume的時候Activity才顯示到前臺。
- **onPause——表示Activity正在停止,正常情況下,onStop就會被調用。**在特殊情況下,如果這個時候快速的再回到當前Activity,那麼onResume就會被調用。任玉剛猜測這種情況屬於幾段情況,用戶操作很難重現這一場景,此時可以做一些存儲數據、停止動畫等工作,不能太耗時,因爲會影響到新Activity的顯示。
- onStop——表示Activity即將停止,可以做一些稍微重量級的回收工作,但是不能太耗時
- onDestroy——表示Activity即將銷燬,這是Activity聲明週期中最後一個回調。我們可以做一些回收工作和最終的資源釋放。
情景分析
- 對於一個第一次啓動的Activity,調用如下:onCreate——onStart——onResume
- 當打開新Activity、切換到桌面,調用如下:onPause——onStop,當Activity採用了透明主題,那麼就不會回調onStop。
- 再次回到原Activity時,調用如下:onRestart——onStart——onResume
- 點擊返回鍵時,調用如下:onPause——onStop——onDestroy
- Activity回收重建時的生命週期和過程一樣。
- 對於整個生命週期:onCreate和onDestroy是配對的,分別對應創建和銷燬。
- 從Activity可見來說,onStart和onStop是配對的。
- 從Activity是否在前臺來說,onResume和onPause是配對的。
兩個問題
問題1: onStart 和onResume onPause 和onStop從描述上來看差不多,對我們來說有
什麼實質的不同呢?
從實際使用過程來說,onStart和onResume、onPause和onStop看起來的確差不多。
系統爲什麼還要提供看起來重複的接口呢?根據上面的分析,我們知道這兩個回調錶示不同的意義,onStart和onStop是從Activity是否可見這個角度回調的,onResume和onPause是從Activity是否位於前臺這個角度回調的。
問題2:假設當前Activity爲A,如果這時用戶打開一個新Activity B,那麼B的onResume
和A的onPause哪個先執行呢?
對於這個問題可以直接回答:先執行A的onPause,在執行B的onResume。
這個就要追溯到源碼了,有點囉嗦,這裏就直接給出結論。
源碼中在新Activity啓動之前,棧頂的Activity需要先onPause後,新Activity才能啓動。
異常情況下的週期
情況1
資源相關配置發生改變導致Activity被殺死並重新創建
默認情況下,如果我們的Activity不做特殊處理,那麼當系統配置發生改變後,Activity就會被銷燬並重新創建。
當系統配置發生改變後,Activity 會被銷燬,其onPause、onStop. onDestroy 均會被調
用,同時由於Activity 是在異常情況下終止的,系統會調用onSaveInstanceState來保存當前
Activity的狀態。
這個方法的調用時機是在onStop之前,它和onPause沒有既定的時序關係,它既可能在onPause 之前調用,也可能在onPause 之後調用。需要強調的一點是,這個方法只會出現在Activity 被異常終止的情況下,正常情況下系統不會回調這個方法。
當Activity被重新創建後,系統會調用onRestoreInstanceState, 並且把Activity 銷燬時onSaveInstanceState方法所保存的Bundle對象作爲參數同時傳遞給onRestorelnstanceState
和onCreate方法。因此,我們可以通過onRestoreInstanceState和onCreate方法來判斷Activity
是否被重建了,如果被重建了,那麼我們就可以取出之前保存的數據並恢復,從時序上來
說,onRestoreInstanceState 的調用時機在onStart 之後。
另外,我們要知道,在onSaveInstanceState和onRestoreInstanceState方法中,系統自動
爲我們做了一-定的恢復工作。當Activity 在異常情況下需要重新創建時,系統會默認爲我
們保存當前Activity的視圖結構,並且在Activity重啓後爲我們恢復這些數據,比如文本框
中用戶輸入的數據、ListView 滾動的位置等。
情況2
資源內存不足導致低優先級Activity被殺死
Activity按照優先級從高到低可以分爲如下三種:
- 前臺Activity——正在交互的Activity
- 可見但非前臺——比如Activity中彈出了一個對話框,導致不能與其交互
- 後臺Activity——已經被暫停的Activity,比如執行了onStop
當系統內存不足時,系統就會按照上述優先級去殺死目標Activity 所在的進程,並在
後續通過onSaveInstanceState和onRestoreInstanceState來存儲和恢復數數據。
一些後臺工作不適合脫離四大組件而獨自運行在後臺中,這樣進程很容易被殺死。比較好的方法是將後臺工作放入Service中從而保證進程有一定的優先級, 這樣就不會輕易地被系統殺死。
我們添加這個屬性可以避免在屏幕方向發生改變的時候進行重建。也可以設置其他選項。
加入上面的代碼後,系統屬性更改後Activity便不會重啓,但是會回調onConfigurationChanged方法,這個時候我們就可以做一些自己的特殊處理。