本系列專題以提煉要點的方式總結知識點,而不做具體展開,對應的會附上個人較喜歡的文章連結供大家詳細瞭解和學習。第一個板塊“開發藝術”是對任老師的《Android開發藝術探索》著作的學習和擴充套件,此書的目錄也是該板塊的主線,那麼就先從我們熟悉的Activity開始吧~
在之前的Activity篇主要學習Activity的生命週期、建立和頁面跳轉的實現,本篇將深入瞭解Activity,學習清單:
- 生命週期全解析
- 四種啟動模式
- IntentFilter匹配規則
一.生命週期全解析
1.Q:典型情況下Activity生命週期
A:
a.onCreate()
:
- 狀態:Activity 正在建立
- 任務:做初始化工作,如setViewContent介面資源、初始化資料
- 注意:此方法的傳參Bundle為該Activity上次被異常情況銷燬時儲存的狀態資訊。
b.onStart()
:
- 狀態:Activity 正在啟動,這時Activity 可見但不在前臺,無法和使用者互動。
c.onResume()
:
- 狀態:Activity 獲得焦點,此時Activity 可見且在前臺並開始活動。
d.onPause()
:
- 狀態: Activity 正在停止
- 任務:可做 資料儲存、停止動畫等操作。
- 注意:Activity切換時,舊Activity的onPause會先執行,然後才會啟動新的Activity。
e.onStop()
:
- 狀態:Activity 即將停止
- 任務:可做稍微重量級回收工作,如取消網路連線、登出廣播接收器等。
- 注意:新Activity是透明主題時,舊Activity都不會走onStop。
f.onDestroy()
:
- 狀態:Activity 即將銷燬
- 任務:做回收工作、資源釋放。
g.onRestart()
:
- 狀態:Activity 重新啟動,Activity由後臺切換到前臺,由不可見到可見。
onStart()和onResume()、onPause()和onStop()的區別: onStart與onStop是從Activity是否可見這個角度呼叫的,onResume和onPause是從Activity是否顯示在前臺這個角度來回撥的,在實際使用沒其他明顯區別。
推薦閱讀:對Activity生命週期方法的感性理解
2.Activity生命週期的切換過程
①啟動一個Activity:
- onCreate()-->onStart()-->onResume()
②開啟一個新Activity:
- 舊Activity的onPause() -->新Activity的onCreate()-->onStart()-->onResume()-->舊Activity的onStop()
③返回到舊Activity:
- 新Activity的onPause()-->舊Activity的onRestart()-->onStart()-->onResume()-->新Activity的onStop()-->onDestory();
④Activity1上彈出對話方塊Activity2:
- Activity1的onPause()-->Activity2的onCreate()-->onStart()-->onResume()
⑤關閉螢幕/按Home鍵:
- Activity2的onPause()-->onStop()-->Activity1的onStop()
⑥點亮螢幕/回到前臺:
- Activity2的onRestart()-->onStart()-->Activity1的onRestart()-->onStart()-->Activity2的onResume()
⑦關閉對話方塊Activity2:
- Activity2的onPause()-->Activity1的onResume()-->Activity2的onStop()-->onDestroy()
⑧銷燬Activity1:
- onPause()-->onStop()-->onDestroy()
參考文章:實際體驗Activity生命週期
3.Q:生命週期的各階段
A:
a.完整生命週期: Activity在onCreate()和onDestroy()之間所經歷的。 在onCreate()中完成各初始化操作,在onDestroy()中釋放資源。
b.可見生命週期: Activity在onStart()和onStop()之間所經歷的。 活動對於使用者是可見的,但仍無法與使用者進行互動。
c.前臺生命週期: Activity在onResume()和onPause()之間所經歷的。 活動可見,且可互動。
4.onSaveInstanceState和onRestoreInstanceState
a.出現時機:異常 情況下Activity 重建,非使用者主動去銷燬
b.系統異常終止時,呼叫onSavaInstanceState來儲存狀態。該方法呼叫在onStop之前,但和onPause沒有時序關係。
onSaveInstanceState與onPause的區別: 前者適用於對臨時性狀態的儲存,而後者適用於對資料的持久化儲存。
c.Activity被重新建立時,呼叫onRestoreInstanceState(該方法在onStart之後),並將onSavaInstanceState儲存的Bundle物件作為引數傳到onRestoreInstanceState與onCreate方法。
可通過onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)來判斷Activity是否被重建,並取出資料進行恢復。但需要注意的是,在onCreate取出資料時一定要先判斷savedInstanceState是否為空。另外,谷歌更推薦使用onRestoreInstanceState進行資料恢復。
推薦閱讀:onSaveInstanceState和onRestoreInstanceState詳解
5.Activity異常情況下生命週期分析
a.由於資源相關配置發生改變,導致Activity被殺死和重新建立
例如螢幕發生旋轉:當豎屏切換到橫屏時,會先呼叫onSaveInstanceState來儲存切換時的資料,接著銷燬當前的Activity,然後重新建立一個Activity,再呼叫onRestoreInstanceState恢復資料。
- onSaveInstanceState-->onPause(不定)-->onStop--> onDestroy-->onCreate-->onStart-->onRestoreInstanceState-->onResume
為了避免由於配置改變導致Activity重建,可在AndroidManifest.xml中對應的Activity中設定android:configChanges="orientation|keyboardHidden|screenSize"。此時再次旋轉螢幕時,該Activity不會被系統殺死和重建,只會呼叫onConfigurationChanged。因此,當配置程式需要響應配置改變,指定configChanges屬性,重寫onConfigurationChanged方法即可。
b.由於系統資源不足,導致優先順序低的Activity被回收
①Activity優先順序排序:
- 前臺可見Activity>前臺可見不可互動Activity(前臺Activity彈出Dialog)>後臺Activity(使用者按下Home鍵、切換到其他應用)
②當系統記憶體不足時,會按照Activity優先順序從低到高去殺死目標Activity所在的程式。
③若一個程式沒有四大元件在執行,那麼這個程式將很快被系統殺死。
推薦閱讀:異常情況下的生命週期分析
二.Activity四種啟動模式
1.Q:設定Activity啟動模式的方法
A:
a.在AndroidManifest.xml中給對應的Activity設定屬性android:launchMode="standard|singleInstance|single Task|singleTop"。
b.通過標記位設定,方法是intent.addFlags(Intent.xxx)。
2.Q:Activity的四種LaunchMode
A:
a.standard
:標準模式、預設模式
- 含義:每次啟動一個Activity就會建立一個新的例項。
- 注意:使用ApplicationContext去啟動standard模式Activity就會報錯。因為standard模式的Activity會預設進入啟動它所屬的任務棧,但是由於非Activity的Context沒有所謂的任務棧。
b.singleTop
:棧頂複用模式
- 含義:如果新Activity已經位於任務棧的棧頂,就不會重新建立,並回撥 onNewIntent(intent) 方法。
c.singleTask
:棧內複用模式
- 含義:只要該Activity在一個任務棧中存在,都不會重新建立,並回撥onNewIntent(intent) 方法。如果不存在,系統會先尋找是否存在需要的棧,如果不存在該棧,就建立一個任務棧,並把該Activity放進去;如果存在,就會建立到已經存在的棧中。
d.singleInstance
:單例項模式
- 含義: 具有此模式的Activity只能單獨位於一個任務棧中,且此任務棧中只有唯一一個例項。
標識Activity任務棧名稱的屬性:android:taskAffinity,預設為應用包名。
3.常用的可設定Activity啟動模式的標記位
①FLAG_ACTIVITY_SINGLE_TOP:對應singleTop啟動模式。
②FLAG_ACTIVITY_NEW_TASK :對應singleTask模式。
三.IntentFilter匹配規則
原則: ①一個intent只有同時匹配某個Activity的intent-filter中的action、category、data才算完全匹配,才能啟動該Activity。 ② 一個Activity可以有多個 intent-filter,一個 intent只要成功匹配任意一組 intent-filter,就可以啟動該Activity。
a. action匹配規則:
- 要求intent中的action 存在且必須和intent-filter中的其中一個 action相同。
- 區分大小寫。
b. category匹配規則:
- intent中的category可以不存在,這是因為此時系統給該Activity 預設 加上了 < category android:name="android.intent.category.DEAFAULT" /> 屬性值。
- 除上述情況外,有其他category,則要求intent中的category和intent-filter中的所有category 相同。
c. data匹配規則:
- 如果intent-filter中有定義data,那麼Intent中也必須也要定義date。
- data主要由mimeType(媒體型別)和URI組成。在匹配時通過intent.setDataAndType(Uri data, String type) 方法對date進行設定。
- 要求和action相似:如果沒有指定URI,預設值為content和file; 有多組data規則時,匹配其中一組即可。
採用隱式方式啟動Activity時,可以用PackageManager的resolveActivity方法或者Intent的resolveActivity方法判斷是否有Activity匹配該隱式Intent。
推薦閱讀:Intent和IntentFilter
希望這篇文章對你有幫助~