Activity生命周期
典型生命周期
指在有用戶參與的情況下,Activity經(jīng)歷的生命周期的改變。
正常情況下,Activity會(huì)經(jīng)歷如下的生命周期:
- onCreate,表示Activity正在被創(chuàng)建,可以做一些初始化的工作,比如SetContentView,初始化所需要的數(shù)據(jù)。
- onRestart,表示Activity正在被重啟,一般情況下,當(dāng)當(dāng)前Activity從不可見(jiàn)重新變?yōu)榭梢?jiàn),onRestart被調(diào)用。這種情況一般是用戶的行為導(dǎo)致的,比如用戶按Home鍵切換到桌面,或者用戶打開(kāi)了一個(gè)新的Activity,當(dāng)前的Activity就會(huì)暫停,接著用戶又回到了這個(gè)Activity,就會(huì)出現(xiàn)這種情況。
- onStart,表示Activity正在被啟動(dòng),即將開(kāi)始,這是Activity已經(jīng)可見(jiàn)了,但是還沒(méi)有出現(xiàn)在前臺(tái),還無(wú)法和用戶交互。
- onResume,Activity已經(jīng)可見(jiàn)了,并且出現(xiàn)在前臺(tái)并開(kāi)始活動(dòng)。
- onPause,Activity正在停止,緊接著onStop會(huì)被調(diào)用,可以做一些不耗時(shí)的操作。
- onStop,表示Activity即將停止。
- onDestory,Activity即將被銷毀,可以做一些回收工作和最終的資源釋放。
整個(gè)生命周期如下圖所示:
生命周期
注意事項(xiàng)
- 針對(duì)一個(gè)特定的Activity,第一次啟動(dòng),回調(diào)為onCreate->onStart->onResume
- 用戶打開(kāi)新的Activity或切換到桌面,回調(diào)為onPause->onStop。如果Activity設(shè)置了透明主題,不會(huì)回調(diào)onStop。
- 用戶再次回到原Activity,回調(diào)為onRestart->onStart->onResume 。
- 用戶按back鍵回退時(shí),回調(diào)為onPause->onStop->onDestory。
- 新Activity啟動(dòng)之前棧頂?shù)肁ctivity需要先onPause,新的Activity才啟動(dòng)。
- onStart和onStop是否可見(jiàn),onResume,onPause針對(duì)是否位于前臺(tái)。
異常生命周期
Activity被系統(tǒng)收回或者由于當(dāng)前設(shè)備的Configuration發(fā)生變化從而導(dǎo)致Activity被銷毀重建。
資源相關(guān)的系統(tǒng)配置發(fā)生改變導(dǎo)致Activity被殺死并重新創(chuàng)建
當(dāng)系統(tǒng)配置發(fā)生改變后,Activity被銷毀,其onPause,onStop,onDestory均會(huì)被調(diào)用,同時(shí)由于Activity是在異常情況下終止的,系統(tǒng)會(huì)調(diào)用onSaveInstanceState來(lái)保存當(dāng)前Activity的狀態(tài)。這個(gè)方法的調(diào)用時(shí)機(jī)是在onStop之前,可能在onPause之前也可能在onPause之后。當(dāng)Activity被重新創(chuàng)建后,系統(tǒng)會(huì)調(diào)用onRestoreInstanceState,并把Activity銷毀時(shí)onSaveInstanceState方法所保存的Bundle對(duì)象同時(shí)傳給onRestoreInstanceState和onCreate方法。
onRestoreInstanceState與onCreate的區(qū)別就是onRestoreInstanceState一旦被調(diào)用則參數(shù)肯定不是null。
資源內(nèi)存不足導(dǎo)致低優(yōu)先級(jí)的Activity被殺死
Activity的優(yōu)先級(jí)分為:
- 前臺(tái)Activity,正在和用戶交互的Activity,優(yōu)先級(jí)最高。
- 可見(jiàn)但非前臺(tái)Activity,比如Activity彈出了一個(gè)對(duì)話框,導(dǎo)致Activity可見(jiàn),但是位于后臺(tái)無(wú)法和用戶直接交互。
- 后臺(tái)Activity,已經(jīng)被暫停的Activity,比如執(zhí)行了onStop,優(yōu)先級(jí)最低。
系統(tǒng)配置發(fā)生變化,不重新創(chuàng)建的方法
設(shè)置Activity的configChanges屬性。常用的有l(wèi)ocal,orientation,keyboardHidden。
Activity啟動(dòng)模式
任務(wù)棧是一個(gè)先進(jìn)后出的棧結(jié)構(gòu)。四種啟動(dòng)模式:standard,singleTask,singleTop,singleIntance。
standard
系統(tǒng)默認(rèn)模式,每次啟動(dòng)一個(gè)Activity都會(huì)重新創(chuàng)建一個(gè)新的實(shí)例,不管這個(gè)Activity是否有實(shí)例是否存在。誰(shuí)啟動(dòng)了Activity則activiyt就運(yùn)行在啟動(dòng)他的那個(gè)activity所在的棧中。
如果是非Activity的Context啟動(dòng)了Activity,則需要設(shè)置FLAG_ACTIVITY_NEW_TASK標(biāo)記,這樣啟動(dòng)的時(shí)候就會(huì)為它創(chuàng)建一個(gè)新的任務(wù)棧,這個(gè)時(shí)候待啟動(dòng)的Activity實(shí)際上是以singletask模式啟動(dòng)的。
singleTop
棧頂復(fù)用模式,只有在Activity在棧頂有實(shí)例,則復(fù)用,如果不在棧頂則新建實(shí)例。
singleTask
棧內(nèi)復(fù)用,在同一個(gè)棧內(nèi)只存在一個(gè)實(shí)例,如果已經(jīng)在棧里則清除該實(shí)例頂?shù)乃衅渌鸄ctivity對(duì)象,否則新建一個(gè)實(shí)例。具有清除棧頂操作。
singleInstance
單例模式,整個(gè)應(yīng)用內(nèi)只有一個(gè)實(shí)例。
任務(wù)棧
什么是Activity所需要的任務(wù)棧?從參數(shù)TaskAffinity說(shuō)起,該單詞可翻譯為任務(wù)相關(guān)性,這個(gè)參數(shù)表示了一個(gè)Activity所需要的任務(wù)棧的名字,默認(rèn)情況下,所有Activity所需的任務(wù)棧的名稱為應(yīng)用的報(bào)名。TaskAffinity屬性主要和SingleTask啟動(dòng)模式或者allowTaskReparenting屬性配對(duì)使用,其他情況下沒(méi)有意義。另外任務(wù)棧分為前臺(tái)任務(wù)棧和后臺(tái)任務(wù)棧,后臺(tái)任務(wù)棧中的Activity位于暫停狀態(tài),用戶可以通過(guò)切換將后臺(tái)任務(wù)棧再次調(diào)到前臺(tái)。
當(dāng)TaskAffinity和singleTask啟動(dòng)模式配對(duì)使用的時(shí)候,它具有該模式的Activity的目前任務(wù)棧的名稱,待啟動(dòng)的Activity會(huì)運(yùn)行在名字和TaskAffinity相同的任務(wù)棧中。
啟動(dòng)模式的指定
兩種方式,1.在AndroidMenifest文件中為Activity指定,設(shè)置android:launchMode屬性。2.在Intent中設(shè)置標(biāo)記位,通過(guò)intent的addFlags方法來(lái)設(shè)置。
兩種方式區(qū)別,優(yōu)先級(jí)第二種高,限定范圍不同,第一種無(wú)法直接為Activity設(shè)置FLAG_ACTIVITY_CLEAR_TOP,第二種無(wú)法為Activity指定singleInstance模式。
Activity的Flags
- FLAG_ACTIVITY_NEW_TASK 相當(dāng)于為Activity指定了‘singleTask’啟動(dòng)模式
- FLAG_ACTIVITY_SINGLE_TOP 相當(dāng)于制定了‘singleTop’啟動(dòng)模式
- FLAG_ACTIVITY_CLEAR_TOP 當(dāng)啟動(dòng)時(shí),同一個(gè)任務(wù)棧中所有的位于它上面的Activity都要出棧。這個(gè)模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用,這種情況下,被啟動(dòng)的Activity如果已經(jīng)存在,那么系統(tǒng)就會(huì)調(diào)用它的onNewIntent。如果被啟動(dòng)的Activity采用的時(shí)standard模式,則它連同它之上的Activity都要出棧,系統(tǒng)會(huì)創(chuàng)建新的Activity
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS Activity不會(huì)出現(xiàn)在歷史Activity列表中。等同于android:excludeFromRecents="true"。
IntentFilter匹配規(guī)則
Activity的啟動(dòng)分為顯示和隱式調(diào)用。顯示調(diào)用需要明確地指定啟動(dòng)對(duì)象的組件信息,包括包名和類名,而隱式調(diào)用則不需要明確指定組件信息,原則上一個(gè)Intent不應(yīng)該既是顯示調(diào)用又是隱式調(diào)用,如果二者共存的話以顯示調(diào)用為主。
IntentFilter中的過(guò)濾信息有action,category,data。
action匹配規(guī)則
action是一個(gè)字符串,action的匹配規(guī)則是Intent中的action必須能夠和過(guò)濾規(guī)則中得action匹配,這里說(shuō)的匹配指字符串完全一樣。一個(gè)過(guò)濾規(guī)則中可以有多個(gè)action那么只要Intent中的action能夠和過(guò)濾規(guī)則中得任何一個(gè)相同則匹配成功。
category匹配規(guī)則
如果Intent中又category,不管幾個(gè)category,對(duì)于每一個(gè)category,它必須是過(guò)濾規(guī)則中已經(jīng)定義了的category。如果Intent中沒(méi)有category則仍然匹配成功。為了保證activity接收隱式調(diào)用,就必須在intent-filter中指定android.intent.catogroy.DEFAULT這個(gè)category。
data匹配規(guī)則
如果過(guò)濾規(guī)則中定義了data,那么Intent中必須也要定義可匹配的data。
data分為兩部分,mimeType和URI。mimeType指媒體類型,比如image/jpeg,audio/mpeg4-generic等可以表示圖片,文本,視頻等不同的媒體格式。而URI中包含的數(shù)據(jù)就比較多了。URI的結(jié)構(gòu)為:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]
Scheme,URI的模式比如http,file,content等。如果URI中沒(méi)有指定scheme,則整個(gè)URI的其他參數(shù)無(wú)效。
Host,URI的主機(jī)名,必須有Host。
Port,URI中得端口號(hào)。
Path,pathPattern,pathPrefix,三個(gè)參數(shù)表示路徑信息,其中path表示完整的路徑信息,pathPatter也表示完整的路徑信息,但是里面可以包含通配符。pathPrefix表示路徑的前綴。
Intent必須包含data數(shù)據(jù),并且data數(shù)據(jù)能夠完全匹配過(guò)濾規(guī)則中的某一個(gè)data。
Fragment 生命周期
生命周期如下所示:

與activity生命周期對(duì)比:

生命周期分析
- 當(dāng)一個(gè)fragment被創(chuàng)建的時(shí)候,它會(huì)經(jīng)歷以下?tīng)顟B(tài).
- onAttach()
- onCreate()
- onCreateView()
- onActivityCreated()
- 當(dāng)這個(gè)fragment對(duì)用戶可見(jiàn)的時(shí)候,它會(huì)經(jīng)歷以下?tīng)顟B(tài)。
- onStart()
- onResume()
- 當(dāng)這個(gè)fragment進(jìn)入“后臺(tái)模式”的時(shí)候,它會(huì)經(jīng)歷以下?tīng)顟B(tài)。
- onPause()
- onStop()
- 當(dāng)這個(gè)fragment被銷毀了(或者持有它的activity被銷毀了),它會(huì)經(jīng)歷以下?tīng)顟B(tài)。
- onPause()
- onStop()
- onDestroyView()
- onDestroy() // 本來(lái)漏掉類這個(gè)回調(diào),感謝xiangxue336提出。
- onDetach()
- 就像activitie一樣,在以下的狀態(tài)中,可以使用Bundle對(duì)象保存一個(gè)fragment的對(duì)象。
- onCreate()
- onCreateView()
- onActivityCreated()
- fragments的大部分狀態(tài)都和activitie很相似,但fragment有一些新的狀態(tài)。
- onAttached() —— 當(dāng)fragment被加入到activity時(shí)調(diào)用(在這個(gè)方法中可以獲得所在的activity)。
- onCreateView() —— 當(dāng)activity要得到fragment的layout時(shí),調(diào)用此方法,fragment在其中創(chuàng)建自己的layout(界面)。
- onActivityCreated() —— 當(dāng)activity的onCreated()方法返回后調(diào)用此方法
- onDestroyView() —— 當(dāng)fragment中的視圖被移除的時(shí)候,調(diào)用這個(gè)方法。
- onDetach() —— 當(dāng)fragment和activity分離的時(shí)候,調(diào)用這個(gè)方法。
一旦activity進(jìn)入resumed狀態(tài)(也就是running狀態(tài)),你就可以自由地添加和刪除fragment了。因此,只有當(dāng)activity在resumed狀態(tài)時(shí),fragment的生命周期才能獨(dú)立的運(yùn)轉(zhuǎn),其它時(shí)候是依賴于activity的生命周期變化的。
