前言
在一般情況下了解Activity的生命周期后,都很容易認為自己已經理解了生命周期。並且可能會覺得實際運用起來並不需要這么多的生命周期來處理activity。但是Activity的生命周期的設計理念遠遠不止是讓你知道Activity是在創建還是前台還是在后台或者銷毀這般簡單。特別是在初始化與釋放資源的這難點上,只有深入理解了Activity的生命周期才會讓你不會出現以下問題
1.各種資源提早釋放導致空指針
2.各種資源初始化過慢導致空指針
3.資源釋放失敗導致內存泄露
4.反復初始化導致性能開銷大的問題。
生命周期流程圖
講解生命周期
onCreate
特性:
- onCreate是Activity創建時的第一個生命周期,並且只會執行一次
- onCreate執行時Activity處於不可見狀態
- 在這個方法中我們會初始化當前布局setContentLayout()方法
- onCreate執行時Activity的View並沒有測量尺寸繪制,這個時候View的寬高值為0。
建議:
- 不建議進行耗時初始化
- 建議只需要進行只需要一次初始化的View的初始化,比如View的初始化,對話框的初始化,ViewModel的初始化
- 獲取Intent里傳入的值
onStart
特性:
- onCreate()方法完成后,此時activity進入onStart()方法
- 當前activity是用戶可見狀態,但沒有焦點,與用戶不能交互,一般可在當前方法做一些動畫的初始化操作。
- 可以被onRestart重新調用
建議:
- 不建議進行耗時初始化
- View的動畫初始化與開啟
- 一些需要在后台暫停后又重新恢復的初始化,比如一些包含操作View的Handler的重新初始化
- 視頻播放與相機拍照等等功能的重新初始化(比如:Camera2、VideoView)
onResume
特性:
- onStart()方法完成之后,此時activity進入onResume()方法中
- 當前activity狀態屬於運行狀態 (Running),可與用戶進行交互
建議:
- 在重新運行onResume情況下,可以考慮重新恢復視頻播放,注意只是將暫停播放的視頻后的重新恢復。並不是重新初始化視頻播放組件
- 可以考慮Camera預覽可以在這里開啟。
- 在重新運行onResume情況下,恢復Camera預覽。
- 可以考慮動畫在這里開啟。
- 在重新運行onResume情況下,恢復一些動畫View的動畫效果。
- 在重新運行onResume情況下,恢復需要與操作View有關的Callback或者Listener。
- 進行超級耗時的初始化與加載,建議顯示一個等待對話框。這樣頁面已經顯示了,用戶也能看到等待對話框。(但是,因為onResume容易反復調用需要注意需要利用onRestart生命周期做好判斷,防止已經初始化過的資源,進行反復耗時初始化)
onPouse
特性:
- Activity在不在前台時,比如一個Dialog模式的Activity啟動后,處於背景半透明置灰的情況的這個Activity也會觸發onPouse
- 注意!onPouse觸發時,Activity可能處於瞬間可見狀態,並可以進行焦點操作。
- 如果是正常快速跳轉Activity,在進入下一個Activity的瞬間觸發onPouse,這個時候在馬上按返回鍵會直接觸發onResume(不經過onStart生命周期)。
- 在這個生命周期里View是還能被操作並且不會報錯的。(比如改變TextView的字體顏色,字體大小等等操作)
- 在啟動另外一個Activity時,需要先回調當前前台Activity的onPouse生命周期,才能回調需要啟動Activity的onCreate() -> onStart() -> onResume(),這就意味着請不要在onPouse生命周期里做耗時的操作,否則會讓需要前台的Activity有明顯的延遲
建議:
- 暫停視頻播放
- 暫停攝像拍照預覽
- 暫停動畫
- 保存一些需要永久保存的UI值。
- 保存一些UI的臨時值,方便下一次執行onResume的時候恢復顯示。比如一些UI單選結果、多選結果,EditText里的內容。
- 釋放與操作View有關的Callback或者Listener
onStop
特性:
- onPouse()方法完成之后,此時activity進入onStop()方法
- 在此生命周期Activity對用戶是不可見的
- 在系統內存緊張的情況下,有可能會被系統進行回收。所以一般在當前方法可做資源回收。
- 在這個生命周期下操作View會報錯
建議:
- 假設有Handler需要處理View,那么需要在這個生命周期里移除Handler里的所有待發消息。(handler.removeCallbacksAndMessages(null);)
- 釋放Camera2或者Camera的資源。
- 釋放視頻播放VideoView的資源。
- 需要耗時釋放的資源與后台操作建議放到此處進行。
onRestart
特性:
- onRestart()方法在用戶按下home()之后,再次進入到當前activity的時候調用。調用順序onPouse()->onStop()->onRestart()->onStart()->onResume().
- 判斷下一個生命周期onStart()是Activity恢復還是首次創建Activity。
建議:
1.增加一些判斷給后續onStart或者onResume的生命周期里確定此activity是首次啟動還是進入后台恢復的。這樣可以避免一些重量級資源重復初始化。
onDestroy
特性:
- Activity被銷毀錢最后一個被調用的方法。
- Activity不可見。
- 在這個生命周期下操作View會報錯。
- 這個生命周期並不會在Activity進入后台后馬上執行,是否執行釋放Activity是交給系統決定的。所以有概率執行onDestroy方法會延后。
建議:
- 釋放一些實例節約空間,如置空List集合、Bean數據等。
- 操作耗時釋放的資源。
- 置空Handler。
常見情況生命周期的執行順序
第一次啟動 | onCreate() -> onStart() -> onResume() |
從 A 跳轉到 B | A_onPause() -> B_onCreate() -> B_onStart() -> B_onResume() -> A_onStop() |
從 B 再次回到 A | B_onPause() -> A_onRestart() -> A_onStart() -> A_onResume() -> B_onStop() |
用戶按 home 鍵 | onPause() -> onStop() |
按 home 鍵后回到應用 | onRestart() -> onStart() -> onResume() |
用戶按電源鍵屏保 | onPause() -> onStop() |
用戶按電源鍵亮屏 | onRestart() -> onStart() -> onResume() |
用戶按 back 鍵回退 | onPause() -> onStop() -> onDestroy() |
End