 activity生命周期詳(xiang)解,大牛教會你
							時間:2018-07-12      來源:未知(zhi)
							activity生命周期詳(xiang)解,大牛教會你
							時間:2018-07-12      來源:未知(zhi) 
							Activity和BroadcastReceiver ,Service ,contentprovider 并稱(cheng)為Android 四大組件,對(dui)于他(ta)們(men)來說構成了Android應用(yong)的骨架,缺一不可,對(dui)于Activity來說,更是他(ta)們(men)之中的重中之重。
首(shou)先(xian)學(xue)習Activity,需(xu)要先(xian)了解一下他的作用:
在日常應用中Activity是(shi)與(yu)用戶交互(hu)的(de)(de)接口,它提供了一個用戶完成相關操(cao)作(zuo)的(de)(de)窗(chuang)口。當我們(men)(men)在開發中創建Activity后,通過(guo)調(diao)用setContentView(View)方(fang)法(fa)來給該Activity指定一個布局(ju)界面,而這個界面就(jiu)是(shi)提供給用戶交互(hu)的(de)(de)接口。Android系統中是(shi)通過(guo)Activity棧的(de)(de)方(fang)式來管理Activity的(de)(de),而Activity自身則是(shi)通過(guo)生命(ming)周(zhou)期的(de)(de)方(fang)法(fa)來管理的(de)(de)自己的(de)(de)創建與(yu)銷毀,既(ji)然如(ru)此,現在我們(men)(men)就(jiu)來看(kan)看(kan)Activity生命(ming)周(zhou)期是(shi)如(ru)何運作(zuo)的(de)(de)。
其(qi)次對于(yu)Activity來說是有一個(ge)運行狀態(tai)的(de),就好(hao)(hao)比當我們的(de)頁面處于(yu)屏幕的(de)最前端,處于(yu)陰影狀態(tai),處于(yu)后臺中等等又可細分為(wei)好(hao)(hao)幾種狀態(tai):
Active/Running:
Activity處于(yu)(yu)活動狀態(tai),此時Activity處于(yu)(yu)棧頂,是可(ke)見狀態(tai),可(ke)與用(yong)戶(hu)進(jin)行交互。
Paused:
當Activity失(shi)去焦(jiao)點時,或(huo)(huo)被一(yi)(yi)個(ge)新的(de)非全屏的(de)Activity,或(huo)(huo)被一(yi)(yi)個(ge)透明的(de)Activity放(fang)置在(zai)棧頂時,Activity就轉化為Paused狀態(tai)。但我們需要明白,此時Activity只是失(shi)去了與用戶交互(hu)的(de)能力,其(qi)所有的(de)狀態(tai)信(xin)息及其(qi)成員變(bian)量都還存在(zai),只有在(zai)系統內存緊張的(de)情況(kuang)下,才有可能被系統回收掉(diao)。
Stopped:
當一(yi)個Activity被另一(yi)個Activity完全(quan)覆蓋時,被覆蓋的(de)Activity就會進入Stopped狀態,此時它不再可見(jian),但是跟(gen)Paused狀態一(yi)樣保持著其(qi)所有狀態信息及其(qi)成(cheng)員變量。
Killed:
當Activity被系統回(hui)收掉時,Activity就處(chu)于Killed狀態。
Activity會在(zai)以上四種形態中相(xiang)互切(qie)換,至于如何(he)切(qie)換,這因用戶的操作不(bu)同而異。
了(le)解了(le)Activity的(de)4種形態后,我們(men)就(jiu)來(lai)聊聊Activity的(de)生命周期。
 
相信大(da)部分(fen)人對這種(zhong)流程(cheng)圖并不陌生,嗯,我們(men)下(xia)面主要聊得話(hua)題(ti)就(jiu)是圍繞這張(zhang)流程(cheng)圖了。我們(men)先有個大(da)概(gai)印象,后面我們(men)分(fen)析完后再回來看,就(jiu)相當(dang)清晰(xi)了。
所謂的(de)典型的(de)生(sheng)命周期就是在有用(yong)戶參與(yu)的(de)情況(kuang)下,Activity經歷從創(chuang)建(jian),運行(xing),停止,銷(xiao)毀等正常的(de)生(sheng)命周期過程。我們這里先來介紹(shao)一下幾個主要方法的(de)調(diao)用(yong)時機,然后再通(tong)過代碼層面來驗(yan)證其(qi)調(diao)用(yong)流程。
onCreate : 該方(fang)(fang)法(fa)是在Activity被(bei)創建時回調,它是生命周期第一(yi)個(ge)調用的方(fang)(fang)法(fa),我們在創建Activity時一(yi)般都需(xu)要重寫該方(fang)(fang)法(fa),然后在該方(fang)(fang)法(fa)中做(zuo)一(yi)些(xie)初(chu)始化的操作,如通過setContentView設置界面(mian)布局(ju)的資源,初(chu)始化所需(xu)要的組件信息(xi)等。
onStart : 此方法(fa)被回調時表示Activity正(zheng)在啟動,此時Activity已處于可(ke)見狀態,只是還沒有在前臺顯示,因此無(wu)法(fa)與用戶進行交(jiao)互。可(ke)以簡(jian)單理解為Activity已顯示而(er)我們無(wu)法(fa)看見擺了(le)。
onResume : 當(dang)此方(fang)法(fa)(fa)(fa)(fa)回調(diao)時(shi),則說(shuo)明Activity已在(zai)前臺(tai)(tai)可(ke)見(jian),可(ke)與用(yong)戶(hu)交互了(處于前面所說(shuo)的(de)(de)Active/Running形態),onResume方(fang)法(fa)(fa)(fa)(fa)與onStart的(de)(de)相同點(dian)是兩者(zhe)都表示Activity可(ke)見(jian),只不過onStart回調(diao)時(shi)Activity還是后(hou)臺(tai)(tai)無法(fa)(fa)(fa)(fa)與用(yong)戶(hu)交互,而onResume則已顯(xian)示在(zai)前臺(tai)(tai),可(ke)與用(yong)戶(hu)交互。當(dang)然(ran)從流程圖,我們(men)也(ye)(ye)可(ke)以看出當(dang)Activity停止后(hou)(onPause方(fang)法(fa)(fa)(fa)(fa)和onStop方(fang)法(fa)(fa)(fa)(fa)被調(diao)用(yong)),重新回到前臺(tai)(tai)時(shi)也(ye)(ye)會調(diao)用(yong)onResume方(fang)法(fa)(fa)(fa)(fa),因(yin)此我們(men)也(ye)(ye)可(ke)以在(zai)onResume方(fang)法(fa)(fa)(fa)(fa)中初始化一些資(zi)源,比如(ru)重新初始化在(zai)onPause或(huo)者(zhe)onStop方(fang)法(fa)(fa)(fa)(fa)中釋放的(de)(de)資(zi)源。
onPause : 此(ci)(ci)方(fang)法(fa)(fa)(fa)被(bei)回(hui)(hui)調(diao)時則表示(shi)Activity正在(zai)停止(zhi)(Paused形態),一般情況(kuang)下onStop方(fang)法(fa)(fa)(fa)會(hui)緊接(jie)著被(bei)回(hui)(hui)調(diao)。但通過(guo)流程圖我們(men)還(huan)可(ke)以看到一種情況(kuang)是onPause方(fang)法(fa)(fa)(fa)執(zhi)行后(hou)(hou)直接(jie)執(zhi)行了(le)onResume方(fang)法(fa)(fa)(fa),這屬于比(bi)較(jiao)極端的(de)現(xian)象了(le),這可(ke)能是用戶操作使當前Activity退(tui)居(ju)后(hou)(hou)臺后(hou)(hou)又迅速地再回(hui)(hui)到到當前的(de)Activity,此(ci)(ci)時onResume方(fang)法(fa)(fa)(fa)就會(hui)被(bei)回(hui)(hui)調(diao)。當然(ran),在(zai)onPause方(fang)法(fa)(fa)(fa)中我們(men)可(ke)以做一些數據存(cun)儲(chu)或(huo)者動畫(hua)停止(zhi)或(huo)者資源回(hui)(hui)收(shou)的(de)操作,但是不能太耗時,因為這可(ke)能會(hui)影(ying)響到新的(de)Activity的(de)顯示(shi)——onPause方(fang)法(fa)(fa)(fa)執(zhi)行完成后(hou)(hou),新Activity的(de)onResume方(fang)法(fa)(fa)(fa)才會(hui)被(bei)執(zhi)行。
onStop : 一般在onPause方(fang)法執(zhi)(zhi)行完成直接執(zhi)(zhi)行,表(biao)示Activity即將停止(zhi)或者完全被覆(fu)蓋(Stopped形態(tai)),此時(shi)Activity不(bu)可見,僅(jin)在后臺運行。同(tong)樣(yang)地,在onStop方(fang)法可以(yi)做一些資源釋放的操作(不(bu)能太耗時(shi))。
onRestart :表(biao)示Activity正在重新啟動(dong),當Activity由不(bu)可見變為可見狀態時,該方(fang)法被(bei)回(hui)(hui)調。這(zhe)種(zhong)情況一(yi)般是用戶(hu)打開了(le)一(yi)個新的Activity時,當前(qian)的Activity就會被(bei)暫停(ting)(onPause和(he)onStop被(bei)執行了(le)),接著又回(hui)(hui)到當前(qian)Activity頁(ye)面時,onRestart方(fang)法就會被(bei)回(hui)(hui)調。
onDestroy :此(ci)時Activity正在被銷毀,也是生命周期最(zui)后(hou)一個執行的方法,一般我們可以在此(ci)方法中(zhong)做一些回(hui)收工作和(he)最(zui)終的資源釋放。
下(xia)面我們通過程(cheng)序來驗證上(shang)面流程(cheng)中的幾種比較重要(yao)的情(qing)況,同時觀察(cha)生(sheng)命周(zhou)期方(fang)法(fa)的回(hui)調(diao)時機。
說完(wan)生(sheng)命周期,現在(zai)我們在(zai)來說說加載模式
Standard:
默(mo)認(ren)(ren)模(mo)(mo)式(shi),可(ke)以不用寫配置。在(zai)這(zhe)個模(mo)(mo)式(shi)下(xia),都會默(mo)認(ren)(ren)創建一個新的實例。因此(ci),在(zai)這(zhe)種(zhong)模(mo)(mo)式(shi)下(xia),可(ke)以有(you)多個相同的實例,也允(yun)許多個相同Activity疊加(jia)。
例如:
若我有一個Activity名為A1, 上面有一個按鈕(niu)可跳轉到A1。那么(me)如果我點擊按鈕(niu),便會新啟(qi)一個Activity A1疊在(zai)(zai)剛(gang)才的A1之上,再點擊,又會再新啟(qi)一個在(zai)(zai)它之上……
點back鍵(jian)會(hui)依照棧順序依次退出(chu)。
singleTop
可(ke)以有多個實例,但是(shi)不允許多個相同(tong)Activity疊加。即,如果(guo)Activity在棧頂的時(shi)候,啟動相同(tong)的Activity,不會創(chuang)建新的實例,而會調用其(qi)onNewIntent方(fang)法(fa)。
例如:
若(ruo)我有兩個(ge)Activity名為B1,B2,兩個(ge)Activity內(nei)容功能(neng)完全相同(tong),都有兩個(ge)按鈕可以跳(tiao)到B1或者(zhe)B2,唯一不同(tong)的(de)是B1為standard,B2為singleTop。
若(ruo)我意(yi)圖打開的順序為(wei)B1->B2->B2,則實際(ji)(ji)打開的順序為(wei)B1->B2(后一次意(yi)圖打開B2,實際(ji)(ji)只調用(yong)了前一個(ge)的onNewIntent方法)
若(ruo)我(wo)意圖打開的順序為(wei)B1->B2->B1->B2,則實際打開的順序與意圖的一(yi)致,為(wei)B1->B2->B1->B2。
singleTask
只有(you)一(yi)個實(shi)例。在(zai)(zai)同一(yi)個應(ying)用(yong)程(cheng)序中啟(qi)動他的時候,若Activity不存(cun)在(zai)(zai),則(ze)會在(zai)(zai)當前task創(chuang)建(jian)一(yi)個新的實(shi)例,若存(cun)在(zai)(zai),則(ze)會把task中在(zai)(zai)其之上的其它Activity destory掉并調用(yong)它的onNewIntent方法(fa)。
如果是在別的應(ying)用程序中(zhong)(zhong)啟(qi)動它,則會新建(jian)一個(ge)task,并(bing)在該task中(zhong)(zhong)啟(qi)動這個(ge)Activity,singleTask允許別的Activity與(yu)其在一個(ge)task中(zhong)(zhong)共存,也(ye)就是說,如果我在這個(ge)singleTask的實例(li)(li)中(zhong)(zhong)再打(da)開新的Activity,這個(ge)新的Activity還是會在singleTask的實例(li)(li)的task中(zhong)(zhong)。
例如:
若我的(de)應用程序中(zhong)有三(san)(san)(san)個(ge)Activity,C1,C2,C3,三(san)(san)(san)個(ge)Activity可互(hu)相啟(qi)動,其中(zhong)C2為singleTask模(mo)式,那么(me),無論我在(zai)這(zhe)個(ge)程序中(zhong)如何(he)點(dian)擊啟(qi)動,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在(zai)多個(ge)實例,但是C2只會存在(zai)一個(ge),并且(qie)這(zhe)三(san)(san)(san)個(ge)Activity都在(zai)同一個(ge)task里面(mian)。
但是(shi)C1->C2->C3->C2->C3->C1-C2,這樣(yang)的(de)(de)操作過程實際(ji)應該是(shi)如下這樣(yang)的(de)(de),因為singleTask會把task中在(zai)其之上的(de)(de)其它Activity destory掉。
操作:C1->C2 C1->C2->C3 C1->C2->C3->C2 C1->C2->C3->C2->C3->C1 C1->C2->C3->C2->C3->C1-C2
實際:C1->C2 C1->C2->C3 C1->C2 C1->C2->C3->C1 C1->C2
若是別的應用程(cheng)序打(da)開C2,則會新(xin)啟一(yi)個task。
如(ru)別的(de)(de)應用Other中有一個(ge)activity,taskId為200,從它打開(kai)(kai)C2,則C2的(de)(de)taskIdI不會為200,例如(ru)C2的(de)(de)taskId為201,那么(me)再從C2打開(kai)(kai)C1、C3,則C2、C3的(de)(de)taskId仍為201。
注意:如果此時(shi)你點擊home,然后再打開Other,發(fa)現這(zhe)時(shi)顯示的(de)(de)肯(ken)定會(hui)(hui)是Other應用中(zhong)的(de)(de)內容(rong),而不會(hui)(hui)是我(wo)們應用中(zhong)的(de)(de)C1 C2 C3中(zhong)的(de)(de)其(qi)中(zhong)一個(ge)。
singleInstance
只有(you)(you)一個實例,并且(qie)這個實例獨(du)立(li)運(yun)行(xing)在(zai)一個task中,這個task只有(you)(you)這個實例,不允許有(you)(you)別的Activity存在(zai)。
例如:
程序有三個ActivityD1,D2,D3,三個Activity可互相(xiang)啟(qi)(qi)(qi)動(dong),其中D2為singleInstance模式。那么(me)程序從D1開始運(yun)行,假設D1的(de)taskId為200,那么(me)從D1啟(qi)(qi)(qi)動(dong)D2時(shi)(shi),D2會新(xin)啟(qi)(qi)(qi)動(dong)一個task,即(ji)D2與D1不在一個task中運(yun)行。假設D2的(de)taskId為201,再從D2啟(qi)(qi)(qi)動(dong)D3時(shi)(shi),D3的(de)taskId為200,也就(jiu)是說它被壓到了D1啟(qi)(qi)(qi)動(dong)的(de)任務(wu)棧中。
若是在(zai)別的(de)應用程序打開(kai)D2,假(jia)設Other的(de)taskId為200,打開(kai)D2,D2會(hui)新(xin)建一個task運行(xing),假(jia)設它(ta)的(de)taskId為201,那么(me)如果這時再(zai)從D2啟動D1或者D3,則(ze)又(you)會(hui)再(zai)創(chuang)建一個task,因此,若操作(zuo)步驟為other->D2->D1,這過(guo)程就涉(she)及到了3個task了。