Android四大元件之Activity-生命週期
一. Android 四大元件包括
- Activity 活動
- Service 服務
- Broadcast Receiver 廣播接收者
- Content Provider 內容提供者
1.什麼是Activity?
使用者可與其提供的螢幕進行互動,以執行撥打電話、拍攝照片、傳送電子郵件或檢視地圖等操作。 每個 Activity 都會獲得一個用於繪製其使用者介面的視窗。視窗通常會充滿螢幕,但也可小於螢幕並浮動在其他視窗之上。
2.正常情況下生命週期的分析
- onCreate() 表示Activity正在被建立,生命週期的第一個方法。進行一些初始化工作。
- onRestart() 表示Activity正在重新啟動,一般表示當前不可見變為可見時,呼叫。(例:使用者按了Home鍵後重新進入APP)。
- onStart() 表示Activity正在被啟動,狀態可見當不可與使用者進行互動。
- onResume() 表示Activity已經可見並可與使用者進行互動。
- onPause() 表示Activity正在被停止,正常情況下onSop()緊接著執行。此時可以執行一些短耗時的資料存貯等操作。可見不可互動。
- onStop() 表示Activity即將停止。不可見,可進行回收操作。
- onDestroy() 表示Activity即將被銷燬,生命週期的最後一個回撥方法。
針對如上描述,引入一張官方生命週期的圖,更加直觀的體現:
針對一個特定的Activity,每種不同條件下的回撥如下:
-
第一次啟動:onCreate()->onStart()->onResume()
-
退回桌面或者開啟新的Activity:onPause()->onStop() ?:新的Activity採用透明主題,那麼當前Activity不會回撥onStop()
-
再次回到Activity:onRestart()->onStart()->onResume()
-
back回退時:onPause()->onStop()->onDestroy()
-
介面跳轉時:舊的Activity先執行onPause()後,新的Activity的才能建立並啟動。
接下來我們去程式碼中實踐一下,看看結果:
class MainActivity : AppCompatActivity() { private val TAG = "wdl" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.d(TAG,"--onCreate--") } override fun onRestart() { super.onRestart() Log.d(TAG,"--onRestart--") } override fun onStart() { super.onStart() Log.d(TAG,"--onStart--") } override fun onResume() { super.onResume() Log.d(TAG,"--onResume--") } override fun onPause() { super.onPause() Log.d(TAG,"--onPause--") } override fun onStop() { super.onStop() Log.d(TAG,"--onStop--") } override fun onDestroy() { super.onDestroy() Log.d(TAG,"--onDestroy--") } }
第一次啟動:
退回桌面:
再次回到介面:
回退:
3.異常情況下生命週期的分析
-
資源相關的系統配置發生改變導致Activity被殺死並重新建立 例:螢幕突然旋轉,由於系統發生了改變。預設情況下Activity就會被銷燬並且重新建立。
**在Activity意外終止時,會回撥onPause(),onStop(),onDestroy()。在onStop之前會呼叫onSaveInstanceState方法儲存當前Activity的狀態。重建後呼叫onRestoreInstanceState方法並且把儲存的Bundle傳遞給onCreateonRestoreInstanceState取出並恢復。onRestoreInstanceState在onStart後呼叫。**
class MainActivity : AppCompatActivity() {
private val TAG = "wdl"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d(TAG, "--onCreate--")
if (savedInstanceState != null) {
val context = savedInstanceState.getString("test")
Log.d(TAG, "--$context--")
}
}
override fun onSaveInstanceState(outState: Bundle?) {
super.onSaveInstanceState(outState)
Log.d(TAG, "--onSaveInstanceState--")
outState!!.putString("test", "wdlwdlwdl")
}
override fun onRestart() {
super.onRestart()
Log.d(TAG, "--onRestart--")
}
override fun onStart() {
super.onStart()
Log.d(TAG, "--onStart--")
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState)
val context = savedInstanceState!!.getString("test")
Log.d(TAG, "--onRestoreInstanceState:$context--")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "--onResume--")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "--onPause--")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "--onStop--")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "--onDestroy--")
}
}
效果: -螢幕豎直方向: -旋轉為水平方向: 2. 資源記憶體不足導致低優先順序Activity被殺死
資料存貯和恢復過程與第一種一致。
Activity按照優先順序從高到低可以分為一下三類:
- 前臺Activity,正在和使用者互動,優先順序最高
- 可見但非前臺–即無法與使用者互動(彈出對話方塊等)
- 後臺Activity,已經暫停的Activity,執行了onStop,優先順序最低
如不想因為螢幕旋轉而重新建立Activity,在AndroidManifest.xml中相應的配置上加上
android:configChanges="orientation|screenSize"
android:configChanges的(常用)值及其含義:
值 | 含義 |
---|---|
locale | 本地位置發生改變,即語言發生變化 |
keyboardHidder | 鍵盤可訪問性發生改變 |
orientation | 螢幕方向發生改變 |
screenSize | 螢幕尺寸資訊發生改變,API13新增,高於13時不新增,螢幕旋轉會導致Activity重啟 |
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Activity中新增:
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
Log.d(TAG, "--onConfigurationChanged:${newConfig!!.orientation}--")
}
監聽螢幕旋轉時的回撥:
可以看到當配置了android:configChanges="orientation|screenSize"屬性之後,再次進行螢幕旋轉,Activity並未進行重建,從圖中可以看到,只是方向發生了改變。