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的生命周期變化的涵但。