2.Activity異常情況下的生命週期分析學習筆記

Activity除了受用戶操作所導致的正常的生命週期方法調度,還有一些異常情況。
    比如:當資源相關的系統配置發生改變以及系統內存不足的時候,Activity就有可能被殺死。
情況可以分爲下面2種。
2.1 資源相關的系統配置發生改變導致Activity被殺死並且創建。
    
    常見的情形比如:常見的手機屏幕旋轉,或者外接入了顯示屏、鍵盤等情況。
    例如,當前的手機目前是橫屏狀態,旋轉了屏幕,這樣導致了系統的配置發生了改變。默認情況下,Activity會經歷一個銷燬重建的過程,當然我們也可以阻止系統重新創建我們的Activity(可以在AndroidManifest.xml中指定Activity的configchanges)。默認情況下,當系統配置發生改變,Activity都會被銷燬並且重新創建。
    問題:配置改變的時候處於後臺的Activity會不會被銷燬,是在什麼時候銷燬,和前臺一致嗎?
    配置改變了以後,Activity會調用onPause,onStop,onDestory,並且,因爲是異常情況下終止,所以,系統會調用onSaveInstanceState來保存當前的Activity的狀態。這個方法是在onStop之前調用的,但是和onPause的時序關係並不一定,可能在onPause前,也可能在onPause後。onSaveInstanceState只會出現在異常停止的情況下,正常的生命週期是不會調用的。當Activity被重新創建後,系統會調用onRestoreInstanceState,並且會吧Activity銷燬時onSaveInstanceState方法保存的Bundle對象作爲參數傳給onRestoreInstanceState和onCreate方法。onRestoreInstanceState調用在onStart之後。
    在onSaveInstanceState和onRestoreInstanceState中,系統自動爲我們做了一些恢復和保存的工作嗎,比如TextView的內容,EditText的輸入文本、ListView滾動的位置、CheckBox的選中狀態,這些和View相關的狀態,系統會爲我們保存和恢復。每個View都有onSaveInstanceState和onRestoreInstanceState。
    在保存和恢復View的時候,系統的工作流程大致如下:
    Activity異常關閉->調用Activity的onSaveInstanceState->Activity委託Window去保存數據->Window委託Window上面最頂層的Layout(ViewGroup類型,一般是DecorView)->頂層Layout再一一通知子元素來保存數據
    這是一種委託思想:上層委託下層,父容器委託子元素來處理這個流程。這個思想在事件分發、View繪製過程中都用到了。

2.2 資源內存不足導致低優先級的Activity被殺死
 
   數據保存和恢復和情況1是一樣的,下面描述一下Activity的優先級情況,Activity按照優先級從高到低可以分爲如下:
    2.2.1 前臺Activity
                正在和用戶交互的Activity,優先級最高。
     2.2.2 可見但是並非是前臺的Activity
                比如當前Activity被彈了一個對話框,或者是頂層有一個透明的Activity
      2.2.3 後臺Activity
                已經執行了onStop,用戶不可見,已經被暫停了,優先級是最低的。
    當內存不足的時候,系統就會按照上述喲西安吉去殺死目標Activity所在的進程,並且後續通過onSaveInstanceState和onRestoreInstanceState來存儲和恢復數據。
    如果一個進程沒有四大組件在執行,那麼這個進程將會很快被系統殺死。因此,一些後臺工作不適合脫離四大組件而獨自運行在後臺中,這樣的話,進程會很容易被殺死,比較好的方法就是把後臺的工作放在Service中保證進程有一定優先級,這樣不會輕易被系統殺死(感覺這就是Android卡頓佔內存的原因了)。

2.3 資源相關配置改變的時候阻止系統殺死Activity
   
     可以通過在AndroidManifest.xml文件中,配置configchanges來屬性,來阻止,比如我們不希望在屏幕改變的時候重新創建,那麼就可以在configchanges屬性中添加orientation,
    如:
    android:configChanges="orientation"
    多個值之間用 | 來連結。
    這樣子的話,在屏幕旋轉的時候就會回調Activity的onConfigChanges方法。需要注意下,在API 13以上,需要用
    android:configChanges="orientation|screenSize"來防止旋轉銷燬Activity.
    
    需要記住以下幾個configChanges的項目和含義。
    locale:設備的本地位置發生了改變,一般是指切換了系統的語言。
    screenLayout:屏幕布局發生了改變,比如使用了新的顯示設備。
    fontScale:系統字體發生了改變,比如用戶選擇了一個新字號。
    uiMode:用戶界面模式發生了改變,比如開啓了夜間模式(API 8增加)
    orientation:屏幕方向發生了改變。
    screenSize:屏幕的尺寸信息發生了改變,和屏幕方向有關,這個選項和編譯選項有關,當編譯選項中的minSdkVersion和targetSdkVersion都低於13,這個選項不會導致Activity的重啓,否則會導致Activity重啓 (API 13新增加)。
     smallestScreenSize:屏幕的物理尺寸信息發生了改變,和屏幕方向無關,這個選項和編譯選項有關,當編譯選項中的minSdkVersion和targetSdkVersion都低於13,這個選項不會導致Activity的重啓,否則會導致Activity重啓 (API 13新增加)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章