1. Activity生命周期
在Android開發(fā)藝術(shù)探索中隐砸,分了兩種場景對Activity的生命周期進(jìn)行介紹:
- 正常生命周期:
onCreate->onStart->onResume->交互->onPause->onStop->onDestroy
注意:從stop狀態(tài)恢復(fù)到活動(dòng)狀態(tài)(返回到上個(gè)Activity、從桌面回到應(yīng)用)會走onRestart->onStart->onResume
- 異常生命周期
交互->onPause->onSaveInstanceState->onStop->onDestroy
onCreate->onStart->onRestoreInstanceState->onResume->交互
異常生命周期中會在onStop之前調(diào)用onSaveInstanceState保存頁面的狀態(tài)(遍歷每個(gè)子View髓堪,保存子Viwe的狀態(tài)宾符,每個(gè)子View都有自己的實(shí)現(xiàn))踢星。然后在重建的過程中可以通過onRestoreInstanceState來恢復(fù)之前保存的狀態(tài)统刮。
那么什么時(shí)候會出現(xiàn)異常生命周期呢?有以下兩種情況:
1. 資源相關(guān)的系統(tǒng)配置發(fā)生改變導(dǎo)致Activity被殺死并重建
比如橫豎屏切換污抬,Activity會重建并且重新加載資源汞贸。我們也可以設(shè)置系統(tǒng)配置發(fā)生變化,Activity不重建:
andriod:configChanges="orientation|screenSize|keyboardHidden|locale"
-
orientation和screenSize
一起使用印机,防止橫豎屏切換重建Activity -
keyboardHidden
防止軟鍵盤彈出隱藏時(shí)重建Activity -
locale
防止切換系統(tǒng)語言導(dǎo)致重建Activity
這些配置可以使Activity不被重建矢腻,取而代之,onConfigurationChanged方法別回調(diào)射赛,可以在該方法中做相應(yīng)處理多柑。
2. 內(nèi)存資源不足導(dǎo)致低優(yōu)先級的Activity被殺死
Activity的優(yōu)先級分3個(gè)等級:
- 前臺Activity(可交互)
- 可見非前臺Activity(可見不可交互)
- 后臺Activity(不可見,執(zhí)行了onStop)
從上到下優(yōu)先級降低楣责,當(dāng)系統(tǒng)內(nèi)存資源不足是竣灌,會從低優(yōu)先級開始?xì)⑺繟ctivity。因此一些后臺任務(wù)不適合脫離四大組件獨(dú)自運(yùn)行腐魂,很容易被殺死帐偎,比較好的是后臺任務(wù)放在service中執(zhí)行逐纬,保證一定的優(yōu)先級蛔屹。
2. Activity啟動(dòng)模式
做Android的都知道Activity有四種啟動(dòng)模式,下面介紹一下各種模式的特點(diǎn):
-
standard
默認(rèn)的啟動(dòng)模式豁生,每次啟動(dòng)都會重新創(chuàng)建一個(gè)實(shí)例
兔毒,被創(chuàng)建的實(shí)例的生命周期是正常的生命周期,即onCreate->onStart->onResume
甸箱,該實(shí)例歸屬于啟動(dòng)它的Activity所屬棧
育叁。通過ApplicationContext啟動(dòng)Activity必須添加標(biāo)志FLAG_ACTIVITY_NEW_TASK,會為即將啟動(dòng)的Activity創(chuàng)建一個(gè)任務(wù)棧芍殖,因?yàn)锳pplicationContext沒有任務(wù)棧豪嗽。 -
singleTop
棧頂復(fù)用模式,如果新Activity已經(jīng)位于棧頂豌骏,則不重新創(chuàng)建
龟梦,不會走正常的生命周期,而會調(diào)用onResume->onNewInstance方法
窃躲。 -
singleTask
棧內(nèi)復(fù)用模式计贰,只要Activity在一個(gè)棧內(nèi)存在,那么多次啟動(dòng)此Activity都不會重新創(chuàng)建實(shí)例
蒂窒,生命周期同singleTop一樣躁倒,會調(diào)用onNewInstance
荞怒,啟動(dòng)流程:系統(tǒng)會先尋找Activity對應(yīng)的任務(wù)棧是否存在,如果不存在秧秉,創(chuàng)建一個(gè)新的任務(wù)棧褐桌,把Activity放到棧中留拾;如果存在疏尿,尋找棧內(nèi)是否存在Activity實(shí)例丹擎,如果不存在钞诡,則創(chuàng)建一個(gè)新的Activity放入棧內(nèi)板祝,如果存在亥宿,則把該Activity調(diào)到棧頂躲惰。該啟動(dòng)模式自帶FLAG_ACTIVITY_CLEAR_TOP乡洼,即清除該Activity只上的其他Activity拇舀。 -
singleInstance
單例模式逻族,加強(qiáng)版singleTask模式,具有singleTask的所有特性
骄崩,具有該模式的Activity只能單獨(dú)位于一個(gè)任務(wù)棧中
聘鳞。被該實(shí)例啟動(dòng)的Activity會運(yùn)行于另一個(gè)任務(wù)棧中
怎么改變Activity所屬任務(wù)棧呢?所有Activity默認(rèn)的任務(wù)棧是應(yīng)用包名要拂,我們也可以給Activity單獨(dú)指定任務(wù)棧抠璃,只需要設(shè)置:
taskAffinity="xxx.xx.x"
,不過taskAffinity必須結(jié)合singleTask或者allowTaskReparenting使用脱惰。
taskAffinity+singleTask
搏嗡,待啟動(dòng)Activity會運(yùn)行在名字和taskAffinity相同的任務(wù)棧中。
taskAffinity+allowTaskReparenting
拉一,當(dāng)應(yīng)用A啟動(dòng)了應(yīng)用B的Activity C采盒,如果這個(gè)C設(shè)置了allowTaskReparenting=true
,那么當(dāng)應(yīng)用B被啟動(dòng)后蔚润,C會直接從應(yīng)用A的任務(wù)棧轉(zhuǎn)移到應(yīng)用B的任務(wù)棧磅氨。
Activity的Flags
此處介紹幾個(gè)比較常用的Flag:
- FLAG_ACTIVITY_SINGLE_TOP:作用同在AndroidManifest中設(shè)置了android:launchMode="singleTop"
- FLAG_ACTIVITY_NEW_TASK:作用同在AndroidManifest中設(shè)置了android:launchMode="singleTask"
- FLAG_ACTIVITY_CLEAR_TOP:當(dāng)啟動(dòng)有此標(biāo)記的Activity時(shí),在同一個(gè)任務(wù)棧中所有位于它上面的Activity都要出棧嫡纠,一般和FLAG_ACTIVITY_NEW_TASK一起使用
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有此標(biāo)記的Activity不會出現(xiàn)在歷史Activity列表中
IntentFilter匹配規(guī)則
主要介紹Activity隱式啟動(dòng)的匹配規(guī)則烦租。隱式調(diào)用需要Intent能夠匹配目標(biāo)組件的IntentFilter中設(shè)置的過濾信息,如果不匹配將無法啟動(dòng)Activity除盏。IntentFilter中設(shè)置的過濾信息有action叉橱、category、data痴颊。
-
action
Intent中的action必須和IntentFilter中的action一樣(字符串赏迟,大小寫敏感)
IntentFilter可設(shè)置多個(gè)action,只要Intent的action于其中一個(gè)匹配成功即算成功
Intent中未設(shè)置action蠢棱,那么匹配失敗 -
category
Intent中設(shè)置了一個(gè)或多個(gè)category锌杀,那么就必須在IntentFilter中都有對應(yīng)的category(字符串)
Intent中沒有category甩栈,算匹配成功,因?yàn)橄到y(tǒng)會默認(rèn)設(shè)置一個(gè)android.intent.category.DEFAULT
糕再,所以支持隱式啟動(dòng)的Activity必須指定android.intent.category.DEFAULT
這個(gè)category -
data
IntentFilter中指定了data量没,那么Intent中必須定義可匹配的data
data的結(jié)構(gòu)包含兩部分:mimeType
和URI
,mimeType指媒體類型突想,URI包含的內(nèi)容較多殴蹄,結(jié)構(gòu)為<schema>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
具體的匹配規(guī)則可以給兩個(gè)例子:
<intent-filter>
<data android:mimeType="image/*"/>
</intent-filter>
//可匹配的intent
intent.setDataAndType(Uri.parse("file://abc"), "image/png");
另外一個(gè):
<intent-filter>
<data android:mimeType="video/mpeg" android:schema="http" .../>
</intent-filter>
//可匹配的intent
intent.setDataAndType(Uri.parse("http://abc"), "video/mpeg");
總結(jié)
本章介紹了Activity的生命周期和啟動(dòng)模式,這些知識點(diǎn)是Android中的基礎(chǔ)猾担,而且也是面試過程中大概率問到的知識點(diǎn)袭灯,必須要掌握。