轉(zhuǎn)載網(wǎng)址: http://blog.sina.com.cn/s/blog_6f3ff2c90101j50x.html
先首先簡單介紹下Task和Activity的關(guān)系
Task就像一個(gè)容器,而Activity就相當(dāng)與填充這個(gè)容器的東西,第一個(gè)東西(Activity)則會處于最下面悔醋,最后添加的東西(Activity)則會在最上面。從Task中取出東西(Activity)是從最頂端取出卤恳,也就是說最先取出的是最后添加的東西(Activity),以此類推寒矿,最后取出的是第一次添加的Activity突琳,而Activity在Task中的順序是可以控制的,在Activity跳轉(zhuǎn)時(shí)用到Intent Flag可以設(shè)置新建activity的創(chuàng)建方式符相;
Intent.FLAG_ACTIVITY_NEW_TASK
默認(rèn)的跳轉(zhuǎn)類型,它會重新創(chuàng)建一個(gè)新的Activity拆融,不過與這種情況蠢琳,比如說Task1中有A,B,C三個(gè)Activity,此時(shí)在C中啟動(dòng)D的話,如果在AndroidManifest.xml文件中給D添加了Affinity的值和Task中的不一樣的話镜豹,則會在新標(biāo)記的Affinity所存在的Task中壓入這個(gè)Activity傲须。如果是默認(rèn)的或者指定的Affinity和Task一樣的話,就和標(biāo)準(zhǔn)模式一樣了啟動(dòng)一個(gè)新的Activity.
FLAG_ACTIVITY_SINGLE_TOP
這個(gè)FLAG就相當(dāng)于加載模式中的singletop趟脂,比如說原來?xiàng)V星闆r是A,B,C,D在D中啟動(dòng)D泰讽,棧中的情況還是A,B,C,D
FLAG_ACTIVITY_CLEAR_TOP
這個(gè)FLAG就相當(dāng)于加載模式中的SingleTask,這種FLAG啟動(dòng)的Activity會把要啟動(dòng)的Activity之上的Activity全部彈出椢羝冢空間已卸。類如:原來?xiàng)V械那闆r是A,B,C,D這個(gè)時(shí)候從D中跳轉(zhuǎn)到B,這個(gè)時(shí)候棧中的情況就是A,B了
FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個(gè)網(wǎng)上很多人是這樣寫的镇眷。如果activity在task存在咬最,拿到最頂端,不會啟動(dòng)新的Activity。這個(gè)有可能會誤導(dǎo)大家欠动! 他這個(gè)FLAG其實(shí)是這個(gè)意思!比如說我現(xiàn)在有A惑申,在A中啟動(dòng)B具伍,此時(shí)在A中Intent中加上這個(gè)標(biāo)記。此時(shí)B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT方式啟動(dòng)圈驼,此時(shí)在B中再啟動(dòng)C人芽,D(正常啟動(dòng)C,D),如果這個(gè)時(shí)候在D中再啟動(dòng)B绩脆,這個(gè)時(shí)候最后的棧的情況是 A,C,D,B萤厅。如果在A,B,C,D正常啟動(dòng)的話,不管B有沒有用FLAG_ACTIVITY_BROUGHT_TO_FRONT啟動(dòng)靴迫,此時(shí)在D中啟動(dòng)B的話惕味,還是會變成A,C,D,B的。
FLAG_ACTIVITY_NO_USER_ACTION
onUserLeaveHint()作為activity周期的一部分玉锌,它在activity因?yàn)橛脩粢D(zhuǎn)到別的activity而要退到background時(shí)使用名挥。比如,在用戶按下Home鍵,它將被調(diào)用主守。比如有電話進(jìn)來(不屬于用戶的選擇)禀倔,它就不會被調(diào)用。
那么系統(tǒng)如何區(qū)分讓當(dāng)前activity退到background時(shí)使用是用戶的選擇参淫?
它是根據(jù)促使當(dāng)前activity退到background的那個(gè)新啟動(dòng)的Activity的Intent里是否有FLAG_ACTIVITY_NO_USER_ACTION來確定的救湖。
注意:調(diào)用finish()使該activity銷毀時(shí)不會調(diào)用該函數(shù)
FLAG_ACTIVITY_NO_HISTORY
意思就是說用這個(gè)FLAG啟動(dòng)的Activity,一旦退出涎才,它不會存在于棧中鞋既,比方說!原來是A,B,C這個(gè)時(shí)候再C中以這個(gè)FLAG啟動(dòng)D的,D再啟動(dòng)E涛救,這個(gè)時(shí)候棧中情況為A,B,C,E畏邢。
Activity有四種加載模式:standard(默認(rèn)), singleTop检吆, singleTask和 singleInstance舒萎。以下逐一舉例說明他們的區(qū)別:
standard:Activity的默認(rèn)加載方法,即使某個(gè)Activity在 Task棧中已經(jīng)存在蹭沛,另一個(gè)activity通過Intent跳轉(zhuǎn)到該activity臂寝,同樣會新創(chuàng)建一個(gè)實(shí)例壓入棧中。例如:現(xiàn)在棧的情況為:A B C D摊灭,在D這個(gè)Activity中通過Intent跳轉(zhuǎn)到D咆贬,那么現(xiàn)在的棧情況為: A B C D D 。此時(shí)如果棧頂?shù)腄通過Intent跳轉(zhuǎn)到B帚呼,則棧情況為:A B C D D B掏缎。此時(shí)如果依次按返回鍵,D D C B A將會依次彈出棧而顯示在界面上煤杀。
singleTop:如果某個(gè)Activity的Launch mode設(shè)置成singleTop眷蜈,那么當(dāng)該Activity位于棧頂?shù)臅r(shí)候,再通過Intent跳轉(zhuǎn)到本身這個(gè)Activity沈自,則將不會創(chuàng)建一個(gè)新的實(shí)例壓入棧中酌儒。例如:現(xiàn)在棧的情況為:A B C D。D的Launch mode設(shè)置成了singleTop枯途,那么在D中啟動(dòng)Intent跳轉(zhuǎn)到D忌怎,那么將不會新創(chuàng)建一個(gè)D的實(shí)例壓入棧中,此時(shí)棧的情況依然為:A B C D酪夷。但是如果此時(shí)B的模式也是singleTop榴啸,D跳轉(zhuǎn)到B,那么則會新建一個(gè)B的實(shí)例壓入棧中捶索,因?yàn)榇藭r(shí)B不是位于棧頂插掂,此時(shí)棧的情況就變成了:A B C D B。
singleTask:如果某個(gè)Activity是singleTask模式腥例,那么Task棧中將會只有一個(gè)該Activity的實(shí)例辅甥。例如:現(xiàn)在棧的情況為:A B C D。B的Launch mode為singleTask燎竖,此時(shí)D通過Intent跳轉(zhuǎn)到B璃弄,則棧的情況變成了:A B。而C和D被彈出銷毀了构回,也就是說位于B之上的實(shí)例都被銷毀了夏块。
singleInstance:將Activity壓入一個(gè)新建的任務(wù)棧中疏咐。例如:Task棧1的情況為:A B C。C通過Intent跳轉(zhuǎn)到D脐供,而D的Launch mode為singleInstance浑塞,則將會新建一個(gè)Task棧2。此時(shí)Task棧1的情況還是為:A B C政己。Task棧2的情況為:D酌壕。此時(shí)屏幕界面顯示D的內(nèi)容,如果這時(shí)D又通過Intent跳轉(zhuǎn)到D歇由,則Task棧2中也不會新建一個(gè)D的實(shí)例卵牍,所以兩個(gè)棧的情況也不會變化。而如果D跳轉(zhuǎn)到C沦泌,則棧1的情況變成了:A B C C糊昙,因?yàn)镃的Launch mode為standard,此時(shí)如果再按返回鍵谢谦,則棧1變成:A B C释牺。也就是說現(xiàn)在界面還顯示C的內(nèi)容,不是D回挽。好了船侧,現(xiàn)在有一個(gè)問題就是這時(shí)這種情況下如果用戶點(diǎn)擊了Home鍵,則再也回不到D的即時(shí)界面了厅各。如果想解決這個(gè)問題,可以為D在Manifest.xml文件中的聲明加上
加上這段之后预柒,也就是說該程序中有兩個(gè)這種聲明队塘,另一個(gè)就是那個(gè)正常的根 activity,在打成apk包安裝之后宜鸯,在程序列表中能看到兩個(gè)圖標(biāo)憔古,但是如果都運(yùn)行的話,在任務(wù)管理器中其實(shí)也只有一個(gè)淋袖。上面的情況點(diǎn)擊D的那個(gè)圖標(biāo)就能回到它的即時(shí)界面(比如一個(gè)EditText鸿市,以前輸入的內(nèi)容,現(xiàn)在回到之后依然存在)即碗。
////////////////////////////////////////////////////////////Intent的常用Flag參數(shù):
FLAG_ACTIVITY_CLEAR_TOP:例如現(xiàn)在的棧情況為:A B C D 焰情。D此時(shí)通過intent跳轉(zhuǎn)到B,如果這個(gè)intent添加
FLAG_ACTIVITY_CLEAR_TOP 標(biāo)記剥懒,則棧情況變?yōu)椋篈 B内舟。如果沒有添加這個(gè)標(biāo)記,則棧情況將會變成:A B C D B初橘。也就是說验游,如果添加了FLAG_ACTIVITY_CLEAR_TOP 標(biāo)記充岛,并且目標(biāo)Activity在棧中已經(jīng)存在,則將會把位于該目標(biāo)activity之上的activity從棧中彈出銷毀耕蝉。這跟上面把B的Launch mode設(shè)置成singleTask類似崔梗。
FLAG_ACTIVITY_NEW_TASK:例如現(xiàn)在棧1的情況是:A B C。C通過intent跳轉(zhuǎn)到D垒在,并且這個(gè)intent添加了FLAG_ACTIVITY_NEW_TASK 標(biāo)記蒜魄,如果D這個(gè)Activity在Manifest.xml中的聲明中添加了Task affinity,并且和棧1的affinity不同爪膊,系統(tǒng)首先會查找有沒有和D的Task affinity相同的task棧存在权悟,如果有存在,將D壓入那個(gè)棧推盛,如果不存在則會新建一個(gè)D的affinity的棧將其壓入峦阁。如果D的Task affinity默認(rèn)沒有設(shè)置,或者和棧1的affinity相同耘成,則會把其壓入棧1榔昔,變成:A B C D,這樣就和不加FLAG_ACTIVITY_NEW_TASK 標(biāo)記效果是一樣的了瘪菌。 注意如果試圖從非activity的非正常途徑啟動(dòng)一個(gè)activity撒会,比如從一個(gè)service中啟動(dòng)一個(gè)activity,則intent比如要添加FLAG_ACTIVITY_NEW_TASK 標(biāo)記师妙。
FLAG_ACTIVITY_NO_HISTORY:例如現(xiàn)在棧情況為:A B C诵肛。C通過intent跳轉(zhuǎn)到D,這個(gè)intent添加FLAG_ACTIVITY_NO_HISTORY標(biāo)志默穴,則此時(shí)界面顯示D的內(nèi)容怔檩,但是它并不會壓入棧中。如果按返回鍵蓄诽,返回到C薛训,棧的情況還是:A B C。如果此時(shí)D中又跳轉(zhuǎn)到E仑氛,棧的情況變?yōu)椋篈 B C E乙埃,此時(shí)按返回鍵會回到C,因?yàn)镈根本就沒有被壓入棧中锯岖。
FLAG_ACTIVITY_SINGLE_TOP:和上面Activity的 Launch mode的singleTop類似介袜。如果某個(gè)intent添加了這個(gè)標(biāo)志,并且這個(gè)intent的目標(biāo)activity就是棧頂?shù)腶ctivity嚎莉,那么將不會新建一個(gè)實(shí)例壓入棧中米酬。
///////////////////////////////////////////////////////////
Activity的主要屬性:
allowTaskReparenting:設(shè)置成true時(shí),和Intent的FLAG_ACTIVITY_NEW_TASK 標(biāo)記類似趋箩。
alwaysRetainTaskStat: 如果用戶長時(shí)間將某個(gè)task 移入后臺赃额,則系統(tǒng)會將該task的棧內(nèi)容彈出只剩下棧底的activity加派,此時(shí)用戶再返回,則只能看到根activity了跳芳。如果棧底的 activity的這個(gè)屬性設(shè)置成true芍锦,則將阻止這一行為,從而保留所有的棧內(nèi)容飞盆。
clearTaskOnLaunch:根activity的這個(gè)屬性設(shè)置成true時(shí)娄琉,和上面的alwaysRetainTaskStat 的屬性為true情況搞好相反。
finishOnTaskLaunch:對于任何activity吓歇,如果它的這個(gè)屬性設(shè)置成true孽水,則當(dāng)task被放置到后臺,然后重新啟動(dòng)后城看,該activity將不存在了女气。