一垃喊、Activity的生命周期:
1宇攻、典型情況下Activity的生命周期(詳見Activity的生命周期的圖):
①onCreate:與onDestory相對應(yīng)抱虐,表示Activity正在被創(chuàng)建亩鬼,這是生命周期的第一個(gè)方法驹针,主要做一些初始化的工作烘挫,比如用setContentView去加載布局資源,初始化Activity等牌捷。耗時(shí)的工作在異步線程上完成
②onStart:與onStop相對應(yīng)墙牌,表示Activity即將開始,這時(shí)的Activity已經(jīng)可見暗甥,但是還沒有出現(xiàn)在前臺喜滨,還無法與用戶交互。
③onResume:表示Activity已經(jīng)可以看見了撤防,并且出現(xiàn)在前臺虽风,可以與用戶產(chǎn)生交互了。
④onPause:與onResume相對應(yīng)寄月,表示Activity正在暫停辜膝,正常情況下,onStop接著就會被調(diào)用漾肮。在特殊情況下厂抖,如果這個(gè)時(shí)候用戶快速地再回到當(dāng)前的Activity,那么onResume會被調(diào)用(極端情況)。一般來說克懊,在這個(gè)生命周期狀態(tài)下忱辅,可以做一些存儲數(shù)據(jù)、停止動畫的工作谭溉,但是不能太耗時(shí)墙懂,如果是由于啟動新的Activity而喚醒的該狀態(tài),那會影響到新Activity的顯示扮念,原因是onPause必須執(zhí)行完损搬,新的Activity的onResume才會執(zhí)行。(Activity此時(shí)是可見的:dialog,或者新Activity的主題是透明的)
⑤onStop:表示Activity即將停止,已經(jīng)不可見巧勤,同樣不能做過多耗時(shí)操作嵌灰。
⑥onDestroy:表示Activity即將被銷毀,這是Activity的最后一個(gè)生命周期踢关,可以做一些回收工作和最終的資源釋放伞鲫。
⑦onRestart:表示Activity正在重新啟動。一般情況下签舞,在當(dāng)前Activity從不可見重新變?yōu)榭梢姷臓顟B(tài)時(shí)onRestart就會被調(diào)用秕脓。這種情形一般是由于用戶的行為所導(dǎo)致的,比如用戶按下Home鍵切換到桌面或者打開了一個(gè)新的Activity(這時(shí)當(dāng)前Activity會暫停儒搭,也就是onPause和onStop被執(zhí)行)吠架,接著用戶有回到了這個(gè)Activity,就會出現(xiàn)這種情況搂鲫。
生命周期圖:
2傍药、注意幾點(diǎn):
①當(dāng)用戶按下Back鍵回退時(shí),回調(diào)onPause,onStop,onDestroy
②HOME鍵的執(zhí)行順序:onPause->onStop->onRestart->onStart->onResume BACK鍵的順序: onPause->onStop->onDestroy->(新的Activity)onCreate->onStart->onResume
③在ActivityA啟動ActivityB的時(shí)候魂仍,需要activityA先執(zhí)行onPause,ActivityB才會創(chuàng)建(onCreate,onStart,onResume)拐辽。
④finish的具體操作:
只是將活動推向后臺,將Activity移出棧擦酌,并沒有及時(shí)的調(diào)用onDestory()方法俱诸,其占用的資源也沒有被及時(shí)釋放
在Activity中的onCreate中調(diào)用finish,則執(zhí)行到的聲明周期方法有:onCreate,onDestroy
在Activity的onStart()中調(diào)用finish()方法,則執(zhí)行的生命周期方法順序?yàn)椋? onCreate() -> onStart() -> onStop() -> onDestroy()
在Activity的onResume()或onPostResume()中調(diào)用finish()方法赊舶,則執(zhí)行的生命周期方法順序?yàn)椋? onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()
⑤Activity的啟動過程:簡單的說就是請求Activity的請求是交給Instrumentation來處理睁搭,然后通過Binder向AMS發(fā)送請求,AMS內(nèi)部維護(hù)一個(gè)ActivityStack并負(fù)責(zé)Activity的狀態(tài)同步笼平,AMS通過ActivityThread去同步Activity的狀態(tài)而完成生命周期方法的調(diào)用(有待擴(kuò)充)园骆。
3、異常情況下Activity的生命周期(Activity被系統(tǒng)回收或者由于當(dāng)前設(shè)備的configuration發(fā)生改變從而導(dǎo)致Activity被銷毀重建):
資源相關(guān)的系統(tǒng)配置發(fā)生改變時(shí)寓调,Activity被殺死并重新創(chuàng)建(比如:Activity處于豎直狀態(tài)锌唾,如果突然旋轉(zhuǎn)屏幕,由于系統(tǒng)配置發(fā)生了改變夺英,在默認(rèn)情況下晌涕,Activity就會被銷毀并且重新創(chuàng)建,當(dāng)然可以阻止系統(tǒng)重新創(chuàng)建新的Activity(android:configChanges="orientation|screenSize")秋麸,加上screenSize是因?yàn)閙inSdkVersion和targetSdkVersion有一個(gè)大于了13。
Activity在異常情況下被終止炬太,系統(tǒng)會調(diào)用onSaveinstanceState來保存當(dāng)前Activity的狀態(tài)灸蟆,并且調(diào)用時(shí)機(jī)是在onStop之前,與onPause沒有特定的時(shí)序關(guān)系。正常情況下,不會調(diào)用這個(gè)方法炒考。當(dāng)新Activity被重新創(chuàng)建的時(shí)候可缚,系統(tǒng)會調(diào)用onRestoreInstanceState來回復(fù)數(shù)據(jù),在onstart之后執(zhí)行onRestoreInstanceState斋枢。
資源內(nèi)存不足導(dǎo)致低優(yōu)先級的Activity被殺死:當(dāng)系統(tǒng)內(nèi)存不足時(shí)帘靡,系統(tǒng)就會按照上述優(yōu)先級去殺死目標(biāo)Activity所在的進(jìn)程,并后續(xù)通過onSaveInstanceState和onRestoreInstanceState來存儲和回復(fù)數(shù)據(jù)瓤帚。
當(dāng)Activity在異常情況銷毀的時(shí)候描姚,系統(tǒng)會默認(rèn)保存當(dāng)前Activity的視圖結(jié)構(gòu),并且在Activity重啟的時(shí)候?yàn)槲覀兓謴?fù)這些數(shù)據(jù)(文本框的輸入數(shù)據(jù)戈次,ListView的滾動位置等)轩勘。保存和恢復(fù)View的層次結(jié)構(gòu),系統(tǒng)的工作流程如下:當(dāng)Activity會調(diào)用onSaveInstanceState去保存數(shù)據(jù)怯邪,然后委托Window去保存數(shù)據(jù)绊寻,接著Window再委托它的上級容器去保存數(shù)據(jù),頂級是一個(gè)Viewgroup,很可能是一個(gè)DecorView,然后頂級容器再去一一通知它的子元素去保存數(shù)據(jù)悬秉。
二澄步、Activity的啟動模式(4種)
1、standard:標(biāo)準(zhǔn)模式
- 每次啟動一個(gè)Activity都會重新創(chuàng)建一個(gè)新的實(shí)例和泌,不管這個(gè)實(shí)例是否已經(jīng)存在村缸。并且誰啟動了這個(gè)Activity,那么這個(gè)Activity就運(yùn)行在啟動它的這個(gè)Activity所在的棧中。
? - 運(yùn)用非Activity的context去啟動一個(gè)Activity時(shí)會出現(xiàn)AndroidRuntimeException異常允跑,主要原因是ApplicationContext沒有所謂的Activity任務(wù)棧王凑,解決辦法是為待啟動的Activity指定:FLAG_ACTIVITY_NEW_TASK的標(biāo)記位,此時(shí)相當(dāng)于singleTask的啟動模式
2聋丝、singleTop:棧頂復(fù)用模式
- 如果新的Activity已經(jīng)位于任務(wù)棧的棧頂索烹,那么此Activity不會被重新創(chuàng)建,同時(shí)它的onNewIntent方法會被調(diào)用弱睦,同時(shí)該Activity的onCreate和onStart則不會被調(diào)用百姓。(注意需要從onNewIntent的intent中獲取新的值,否則用的還是原來intent中的值)
? - 如果新的Activity已經(jīng)位于任務(wù)棧但不是位于棧頂况木,或者棧中不存在垒拢,則這個(gè)Activity會被重新創(chuàng)建(oncreate,onStart,onResume)。
3火惊、singleTask:棧內(nèi)復(fù)用模式(單實(shí)例模式)
- 當(dāng)一個(gè)具有singleTask模式的Activity A 請求啟動求类,系統(tǒng)首先會尋找是否存在A想要的任務(wù)棧(TaskAffinity指定任務(wù)棧的名稱),如果不存在屹耐,就先創(chuàng)建一個(gè)A的任務(wù)棧,并將A的實(shí)例放入棧中尸疆。
? - 如果存在A需要的任務(wù)棧,則首先判斷是否存在A的實(shí)例,如果存在寿弱,則調(diào)用A的onNewIntent犯眠,并將處于A上面的Activity出棧(singleTask自帶clearTop,但是使用標(biāo)志位啟動時(shí)需要使用:FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TOP標(biāo)志位),使得A處于棧頂?shù)奈恢谩? 如果不存在,則創(chuàng)建一個(gè)A的實(shí)例症革,放置于該棧的棧頂筐咧。
4、singleInstance:單實(shí)例模式
- 具有此模式的Activity只能單獨(dú)的位于一個(gè)任務(wù)棧中噪矛。
? - 比如Activity A 是singleInstance模式,當(dāng)A啟動后,系統(tǒng)會為它創(chuàng)建一個(gè)新的任務(wù)棧量蕊。A獨(dú)自運(yùn)行在這個(gè)任務(wù)棧中,后續(xù)的請求均不會創(chuàng)建新的Activity,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀了摩疑。
三危融、TaskAffinity:主要和singleTask啟動模式或者allowTaskReparenting屬性配對使用,其他情況下沒有意義。
- ①當(dāng)TaskAffinity和singleTask啟動模式配對的時(shí)候雷袋,它是具有該模式Activity的目前任務(wù)棧的名字,待啟動的Activity會運(yùn)行在名字和TaskAffinity相同的任務(wù)棧中,Activity默認(rèn)的任務(wù)棧的名稱為包名吉殃。
? - ②當(dāng)TaskAffinity和allowTaskReparenting配對的時(shí)候,當(dāng)應(yīng)用A啟動應(yīng)用B的Activity C后,當(dāng)按下home鍵,再啟動應(yīng)用B時(shí),如果Activity的allowTaskReparenting屬性為true,C會從A的任務(wù)棧轉(zhuǎn)移到B的任務(wù)棧中楷怒。
四蛋勺、如何給Activity指定啟動模式:
- ①在AndroidManifest中指定launchMode.(無法為Activity設(shè)置FLAG_ACTIVITY_CLEAR_TOP標(biāo)識)
? - ②通過Intent(優(yōu)先級更高,但是無法指定singleInstance模式):
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
五、Activity常用的Flags
- ①FLAG_ACTIVITY_NEW_TASK:作用是為Activity指定"singleTask"的啟動模式
? - ②FLAG_ACTIVITY_SINGLE_TOP:作用是為Activity指定"singleTop"的啟動模式
? - ③FLAG_ACTIVITY_CLEAR_TOP:具有此標(biāo)志位的Activity,當(dāng)它啟動時(shí),在同一個(gè)任務(wù)棧中所有位于它上面的Activity都要出棧鸠删,這個(gè)標(biāo)志位一般會和singleTask啟動模式一起出現(xiàn)抱完。
? - ④FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有這個(gè)標(biāo)志位的Activity不會出現(xiàn)在歷史Activity的列表中,當(dāng)某些情況,我們不需要通過歷史列表回到我們的Activity的時(shí)候,這個(gè)標(biāo)記比較有用。其等同于:android:excludeFromRecents = "true".
六刃泡、顯示Intent和隱式Intent:
- ①顯示Intent:(指明了要跳到哪個(gè)Activity或者Service巧娱,包括包名和類名)
Intent intent = new Intent(Activity1.this,Activity2.class)
? - ②隱式Intent:(沒有指明要跳轉(zhuǎn)的類)在AndroidManifest中的intent-filter中實(shí)現(xiàn)過濾。intentFilter的過濾信息有action,category,data.一個(gè)Activity可以有多個(gè)intent-filter,一個(gè)Intent只要能匹配任何一組intent-filter即可成功啟動對應(yīng)的Activity.
? - ③action的匹配規(guī)則:要求Intent的action存在且必須和過濾規(guī)則中的其中一個(gè)action相同烘贴,action區(qū)分大小寫禁添,大小寫不同字符串相同的action會匹配失效。
? - ④category的匹配規(guī)則:category的匹配規(guī)則和action不一樣,要求Intent中如果含有category,那么所有的category都必須和過濾規(guī)則中的某個(gè)category相同桨踪。(Intent可以不設(shè)置category,但是Intent必須設(shè)置action)
? - ⑤data的匹配規(guī)則:與action類似,如果Intent中定義了data,那么Intent中必須定義可匹配的data.
data由兩部分組成,mimeType(媒體類型)和URI(http://www.baidu.com:80/search/info)<shcheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]老翘。
? - ⑥在隱式Intent跳轉(zhuǎn)的時(shí)候,最好做一下IntentFilter的判斷锻离∑糖停看是否有Activity可以匹配的IntentFilter.
- a、采用PackageManager的resolveActivity方法或者Intent的resolveActivity,如果找不到可以匹配的Activity汽纠,就返回空卫键。
- b、PackageManager還提供了queryIntentActivities方法虱朵,不是返回最佳匹配的Activity信息莉炉,而是返回所有成功匹配的Activity的Activity信息啤呼。