1.1Activity的生命週期全面分析

典型情況下的生命週期分析:

正常情況下,Activity會經歷以下的生命週期:

  1. onCreate():這是Activity生命週期的第一個方法,表示Activity正在被創建,我們可以在這個方法裏做些準備工作,比如setContentView(),或者請求Activity所需的一些數據。

  2. onStart():Activity創建出來之後會回調這個方法,表示Activity正在啓動,這個時候Activity已經可見了,但是還在後臺,還不能和用戶進行交互。

  3. onResume():這個時候,Activity已經可見了,並且出現在了前臺,可以和用戶進行交互了。

  4. onPause():表示Activity正在暫停,這個時候,Activity仍然全部或部分可見,但是已經不在前臺了。

  5. onStop():表示Activity正在停止,這個時候Activity已經不可見了,可以在這個方法裏做一些不太耗時的資源釋放操作。

  6. onDestory():表示Activity即將被銷燬,在這裏我們可以做一些回收工作和資源的最終釋放。

Activity的生命週期可以用下圖來表示:

這裏寫圖片描述

這裏再附加一下具體說明:

  • Activity如果已經不可見了,這種情況一般發生在跳轉到了其他的Activity裏,或者用戶按Home健回到桌面,但是Activity的onDestory()方法並沒有被調用,即Activity還沒有被銷燬。當用戶重新回到該Activity時,那麼它會依次調用 onRestart()-> onStart() -> onResume()方法。

  • 如果Activity被系統回收了,當再次打開它時,會重新調用OnCreate()方法。

  • 從整個生命週期來講,onCreate()和onDestory()是配對的,分別標記着Activity的創建和銷燬,並且只可能有一次調用。onStart()和onStop()是配對的,分別標記着Acitvity可見和不可見,隨着用戶的操作可能被調用多次。onResume() 和onPause()是配對的,分別標記着Acitvity的是否在前臺,也有可能被調用多次。

假設當前Activity爲MainAcitvity,如果這時用戶打開一個新的Activity SecondActivity,那麼MainAcitvity 和SecondActivity 的生命週期中的那些方法會被調用呢,調用的順序如何?

經過實際測試,在每個回調裏Log一下,答案是:

這裏寫圖片描述

根據官方的建議,不能在onPause()方法裏做重量級的操作,因爲上一個Activity的onPause()必須執行完,新的Activity才能onResume()。
我們知道,onPause()和onStop()都不宜做耗時操作,尤其是onPause(),因此應當儘量在onStop()中操作,從而使得新的Acitvity可以儘快顯示出來。

異常情況下的生命週期分析:

1. 資源相關配置發生改變導致Activity被殺死並重新創建

在默認情況下,如果我們不做特殊處理,那麼當系統配置發生改變後,比如橫豎屏切換,Acitvity就會被銷燬並重新創建,其生命週期如下圖:

  • 當系統配置發生改變後,Actvity會被銷燬,其onPause(),onStop()和onDestory方法會依次被調用,而且,系統還會調用onSaveInstanceState(),我們可以在這個方法裏做一些狀態保存工作。
  • onSaveInstanceState()方法會在onStop()之前調用,注意它和onResume()沒有既定前後關係。
  • 在Activity被重新創建後,系統會調用onRestoreInstanceState(),並且把Activity被銷燬時onSaveInstanceState()裏保存的Bundle對象作爲參數同時傳給onCreate()和onRestoreInstanceState()。
  • onRestoreInstanceState()會在onStart()之後調用。

2. 資源內存不足導致低優先級的Activity被殺死

當系統內存不足時,系統就會按照優先級去殺死目標Activity所在的進程,並在後續通過onSaveInstanceState()和onSaveInstanceState()來存儲和恢復數據。如果一個進程中沒有四大組件在執行,那麼這個進程將很快被系統殺死,因此一些後臺工作不適合脫離四大組件而獨自在後臺運行,比較好的方法是將後臺工作放在Service中,從而保證進程有一定的優先級。

我們知道,當系統發生改變後,Activity會被銷燬並重新創建,那有沒有方法不重建呢?

答案是有的,如果我們不想系統重建Activity,可以給Activity指定configChanges屬性。比如,不想讓Acitvity在屏幕旋轉時重新創建,就可以給configChanges屬性添加orientation這個值,在AndroidMenifest.xml中的Activity中聲明即可。

android:configChanges = "orientation"`

如果想指定多個值,可以用”|“連接起來,比如:

android:configChanges = "orientation|keyboardHidden|locale"

系統配置中所含的項目是非常多的,常見的有:

“mcc“ 移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機用戶所屬國家;
“mnc“ 移動網號,在一個國家或者地區中,用於區分手機用戶的服務商;
“locale“ 設備的本地位置發生了改變,一般是用戶修改了系統語言;
“keyboard“ 鍵盤類型發生變化,比如用戶接入外部鍵盤設備;
“keyboardHidden“ 鍵盤的可訪問性發生變化,比如用戶調出了鍵盤;
“orientation“ 設備屏幕方向發生了改變,這個是最長用的,比如用戶旋轉了手機屏幕;
“fontScale“ 系統字體縮放比例發生改變,比如用戶選擇了另一個系統字號。

我們可以在Acitvity中複寫onConfigurationChanged()方法,在資源配置發生改變時實現自己的邏輯:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    supper.onConfigurationChanged(newConfig);
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章