本章主要介紹的是Activity和Acitivity調(diào)用棧的分析褐望。
1.Activity
-
Activity形態(tài)(不是Activity生命周期):
- Active/Running:Activity處于棧的最頂層访诱,可見(jiàn),并且與用戶進(jìn)行交互潮罪。
- Paused:當(dāng)Activity失去焦點(diǎn),被一個(gè)新的非全屏的Activity或者一個(gè)透明的Activity放置在棧頂時(shí),Activity就轉(zhuǎn)化為Paused狀態(tài)盯滚。它只是失去了與用戶交互的能力,所有狀態(tài)信息酗电、成員變量都還保持著魄藕,只有內(nèi)存極為不足時(shí)才會(huì)被系統(tǒng)回收。
- Stopped:如果一個(gè)Activity被另一個(gè)Activity完全覆蓋撵术,Activity進(jìn)入Stopped狀態(tài)背率。此時(shí)它不可見(jiàn),但是依然保存了所有信息狀態(tài)還成員變量嫩与。
- Killed:當(dāng)Activity被系統(tǒng)回收掉或者Activity從來(lái)沒(méi)有創(chuàng)建過(guò)寝姿,Activity就處于Killed狀態(tài)。
-
Activity生命周期:
生命周期
生命周期的東西比較基礎(chǔ)簡(jiǎn)單划滋,這里就貼一張圖饵筑,關(guān)于生命周期的資料百度也一堆就不過(guò)多記錄了。
這里記錄一個(gè)Activity重新創(chuàng)建的過(guò)程:如果Activity長(zhǎng)時(shí)間處于stopped狀態(tài)处坪,而此時(shí)系統(tǒng)內(nèi)存也較為緊張時(shí)根资,系統(tǒng)就會(huì)回收Activity。此時(shí)會(huì)將Activity狀態(tài)通過(guò)onSaveInstanceState()
來(lái)保存到Bundle對(duì)象中稻薇,也可以增加額外的鍵值對(duì)存入Bundle中嫂冻。當(dāng)需要重新創(chuàng)建Activity時(shí),保存的Bundle對(duì)象就會(huì)傳遞到Activity的onRestoreInstanceState()
與onCreate()
方法中塞椎。需要注意的是桨仿,如果用戶使用finish()
方法結(jié)束了Activity則不會(huì)調(diào)用。
2.Android任務(wù)棧
當(dāng)啟動(dòng)一個(gè)App時(shí)案狠,如果當(dāng)前環(huán)境中不存在該App的任務(wù)棧服傍,那么系統(tǒng)會(huì)創(chuàng)建一個(gè)任務(wù)棧钱雷,用來(lái)管理這個(gè)App的的Activity。這個(gè)棧也叫作Task吹零,即表若干個(gè)Activity的集合罩抗。另外,一個(gè)Task中的Activity可以來(lái)自不同App灿椅,同一個(gè)App的Activity不一定在一個(gè)Task中套蒂。
3.AndroidMainifest啟動(dòng)模式
Android總共有四種啟動(dòng)模式:
- standard:
默認(rèn)的啟動(dòng)模式,這種啟動(dòng)模式每次都會(huì)創(chuàng)建新的實(shí)例覆蓋在原來(lái)的Activity上茫蛹。 - singleTop:
在啟動(dòng)時(shí)操刀,系統(tǒng)會(huì)判斷當(dāng)前棧頂Activity是不是要啟動(dòng)的Activity,如果是則不創(chuàng)建新的Activity而直接引用它婴洼,如果不是則創(chuàng)建骨坑。這種啟動(dòng)模式通常適用于接受到消息后顯示的界面,例如qq接收到消息后彈出Activity柬采,如果一次來(lái)了10條消息欢唾,顯示的都是同一個(gè)Activity。 - singleTask:
和singleTop相似粉捻,不同之處是這種啟動(dòng)模式會(huì)檢查任務(wù)棧中是否已經(jīng)存在該Activity礁遣,如果存在則將該Activity置頂,并將該Activity以上的Activity都銷毀杀迹。如果是其他app來(lái)以singleTask的模式來(lái)創(chuàng)建這個(gè)Activity時(shí)亡脸,它將創(chuàng)建一個(gè)新的任務(wù)棧。如果該模式的Activity已經(jīng)在后臺(tái)一個(gè)任務(wù)棧中了树酪,那么啟動(dòng)后浅碾,后臺(tái)的這個(gè)任務(wù)棧將一起被切換到前臺(tái),如圖:
singleTask
使用這種模式創(chuàng)建的Activity不是在新的任務(wù)棧中被打開(kāi)续语,就是將已經(jīng)打開(kāi)的Activity切換到前臺(tái)垂谢,所以通常這種模式可以用來(lái)退出整個(gè)應(yīng)用:將主Activity設(shè)為singleTask,然后要退出的Activity轉(zhuǎn)到主Activity疮茄,從而將主Activity上的Activity都清除滥朱,然后重寫(xiě)主Activity的onNewIntent()
方法,在方法中加上一句finish()
力试,將最后一個(gè)Activity結(jié)束掉徙邻。 - singleInstance:
這種啟動(dòng)模式和使用瀏覽器的工作原理類似,在其他程序訪問(wèn)瀏覽器時(shí)畸裳,如果瀏覽器尚未打開(kāi)則會(huì)開(kāi)啟瀏覽器缰犁,否則就會(huì)在已經(jīng)開(kāi)打的瀏覽器上進(jìn)行訪問(wèn)。singleInstance的Activity會(huì)出現(xiàn)在一個(gè)新的任務(wù)棧中,并且該任務(wù)棧只有一個(gè)Activity存在帅容。如果A應(yīng)用創(chuàng)建了一個(gè)singleInstance的Activity颇象,B應(yīng)用想要啟動(dòng)它的時(shí)候則不需要再次創(chuàng)建,兩個(gè)應(yīng)用將共享該Activity并徘。這種啟動(dòng)模式常用于需要與程序分離的界面遣钳。
注意:如果啟動(dòng)模式為singleTop或者singleInstance時(shí),Activity調(diào)用startActivityForResult()
方法來(lái)啟動(dòng)另一個(gè)Activity麦乞,那么系統(tǒng)將直接返回Activity.RESULT_CANCELED
蕴茴,這是由于Framework層對(duì)這兩種模式進(jìn)行了限制,不同Task默認(rèn)是不能傳遞數(shù)據(jù)的姐直,需要通過(guò)Intent才行荐开。
4.Intent Flag啟動(dòng)模式
文中介紹了一些常用的IntentFlag。
- Intent.FLAG_ACTIVITY_NEW_TASK:
使用一個(gè)新的Task來(lái)啟動(dòng)Activity简肴。通常應(yīng)用于Service啟動(dòng)Activity的場(chǎng)景,由于在Service中并不存在Activity棧百侧,所以使用該Flag來(lái)創(chuàng)建一個(gè)新的Activity棧砰识,并創(chuàng)建新的Activity實(shí)例。 - Intent.FLAG_ACTIVITY_SINGLE_TOP:
與指定android:launchMode="singleTop"
同效果佣渴。 - Intent.FLAG_ACTIVITY_CLEAN_TOP:
與指定android:launchMode="singleTask"
同效果辫狼。 - Intent.FLAG_NO_HISTORY:
使用這種模式啟動(dòng)Activity,當(dāng)該Activity啟動(dòng)其他Activity后辛润,該Activity就消失了膨处,不會(huì)保留在Task中。
5.清空任務(wù)棧
系統(tǒng)提供了清空任務(wù)棧的方法來(lái)讓我們將一個(gè)Task全部清除砂竖。通常情況下真椿,可以在AndroidMainifest文件中的<activity>標(biāo)簽中使用以下幾種屬性來(lái)清理任務(wù)棧。
- clearTaskOnLaunch
clearTaskOnLaunch屬性顧名思義乎澄,就是在每次返回該Activity時(shí)突硝,將該Activity之上的Activity都清除。 - finishOnTaskLaunch
當(dāng)離開(kāi)這個(gè)Activity所處的Task置济,那么返回時(shí)解恰,該Activity將被finish。 - alwaysRetainTaskState
如果將Activity這個(gè)屬性設(shè)置為true浙于,那么該Activity所處的Task將不接受任何清理指令护盈,一直保持當(dāng)前Task狀態(tài)。