安卓Activity啟動(dòng)模式詳解

我們知道Activity的啟動(dòng)模式有四種分別為:standard(標(biāo)準(zhǔn)模式)、singleTop(棧頂復(fù)用模式)、singleTask(棧內(nèi)復(fù)用模式)和singleInstance(單一實(shí)例模式),在安卓系統(tǒng)中Activity通過(guò)任務(wù)棧的方式管理Activity痊夭,不同的啟動(dòng)模式實(shí)際上對(duì)應(yīng)的是對(duì)任務(wù)棧的不同操作决左,要想搞明白四種啟動(dòng)模式有什么不同,我們先來(lái)了解一下任務(wù)棧

一 任務(wù)棧

  • 安卓系統(tǒng)通過(guò)任務(wù)棧來(lái)管理Activity
  • 棧具有后進(jìn)先出的特性过咬,每次打開(kāi)一個(gè)Activity都會(huì)進(jìn)行壓棧操作,每次銷(xiāo)毀一個(gè)Activity都會(huì)進(jìn)行出棧操作
  • 任何一個(gè)任務(wù)棧(task)都一定有一個(gè)taskAffinity值制妄,該值與該任務(wù)棧棧底的Acitivity的taskAffinity值相同
  • 每個(gè)Activity都必須有一個(gè)taskAffinity值掸绞,如果沒(méi)有設(shè)置則該值等于application中的taskAffinity值,如果application中也沒(méi)有設(shè)置taskAffinity耕捞,則該值為包名
task.png

二 四種啟動(dòng)模式

Activity啟動(dòng)模式可以在Manifest.xml文件中通過(guò)launchMode屬性設(shè)置衔掸,也可以在代碼中通過(guò)添加Intent的Flag參數(shù)來(lái)設(shè)置

  1. standard(標(biāo)準(zhǔn)模式)
    standard模式每次打開(kāi)Activity都會(huì)新建Activity實(shí)例,不管task(任務(wù)棧)中有沒(méi)有該Activity實(shí)例俺抽,舉個(gè)栗子:
    ActivityA打開(kāi)ActivityB敞映,然后通過(guò)ActivityB打開(kāi)ActivityA,仍會(huì)再創(chuàng)建ActivityA的實(shí)例并放入棧中磷斧,此時(shí)棧的的結(jié)構(gòu)為A->B->A振愿;接著在ActivityA中再打開(kāi)ActivityA,則棧的結(jié)構(gòu)為:A->B->A->A弛饭;如果用戶(hù)想要回退則會(huì)關(guān)閉三次ActivityA冕末,體驗(yàn)十分不友好。
  2. singleTop(棧頂復(fù)用模式)
    顧名思義如果一個(gè)Activity在棧頂孩哑,則需要再次打開(kāi)該Activity時(shí)不用新建該Activity實(shí)例而是調(diào)用該Activity的onNewIntent方法把新的intent傳遞過(guò)來(lái)栓霜,然后復(fù)用該Activity。如果該Activity不在棧頂還是會(huì)創(chuàng)建新的Activity實(shí)例横蜒,下面舉例說(shuō)明:
    假設(shè)有三個(gè)Activity A胳蛮,B,C并且B的啟動(dòng)模式為singleTop
    場(chǎng)景1:任務(wù)棧中只有A丛晌,此時(shí)A啟動(dòng)B仅炊。由于B并不在任務(wù)棧中,因此會(huì)創(chuàng)建B的實(shí)例并放入棧頂澎蛛,任務(wù)棧變?yōu)锳->B效果同standard
    場(chǎng)景2:當(dāng)前任務(wù)棧結(jié)構(gòu)為A->B抚垄,此時(shí)再啟動(dòng)B。由于B已經(jīng)在任務(wù)棧中且位于棧頂,因此會(huì)調(diào)用B的onNewIntent方法呆馁,但不會(huì)新建B的實(shí)例桐经,任務(wù)棧結(jié)構(gòu)仍為A->B
    場(chǎng)景3:當(dāng)前任務(wù)棧的結(jié)構(gòu)為A->B->C,此時(shí)再啟動(dòng)B浙滤。B雖然位于任務(wù)棧的中但不在棧頂阴挣,此時(shí)仍會(huì)創(chuàng)建B的實(shí)例并放入棧頂,任務(wù)棧變?yōu)锳->B->C->B
    singleTop模式下仍會(huì)創(chuàng)建多個(gè)實(shí)例纺腊,如果想在同一個(gè)任務(wù)棧中只有一個(gè)實(shí)例畔咧,就需要使用singleTask模式了
  3. singleTask(棧內(nèi)復(fù)用模式)
    如果一個(gè)Activity的啟動(dòng)模式為singleTask,當(dāng)啟動(dòng)這個(gè)Activity時(shí)揖膜,如果棧中已經(jīng)有了這個(gè)Activity實(shí)例誓沸,不管該Activity實(shí)例在棧中的什么位置都不會(huì)新建該Activity的實(shí)例,而是調(diào)用該Activity的onNewIntent方法并清空該Activity棧上面的其它Activity實(shí)例壹粟,從而讓該Activity位于棧頂拜隧。
    假設(shè)有四個(gè)Activity A,B煮寡,C虹蓄,D并且B的啟動(dòng)模式為singleTask
    場(chǎng)景1:當(dāng)前棧中只有A犀呼,此時(shí)打開(kāi)B幸撕,因?yàn)闂V袥](méi)有B的實(shí)例,所以會(huì)新建B的實(shí)例并放入棧頂外臂,而后棧的結(jié)構(gòu)為A->B
    場(chǎng)景2:當(dāng)前棧的結(jié)構(gòu)為A->B-C-D坐儿,此時(shí)在D中打開(kāi)B,由于棧中已有B的實(shí)例宋光,所以不會(huì)新建B而是調(diào)用B的onNewIntent方法貌矿,并把B上面的Activity實(shí)例清空,而后棧的結(jié)構(gòu)為A->B罪佳;
    一般應(yīng)用于App的主頁(yè)逛漫,從任何入口跳轉(zhuǎn)到主頁(yè)點(diǎn)擊返回都能夠退出App
  4. singleInstance(單一實(shí)例模式)
    設(shè)置為singleInstance的Activity具有全局唯一性,即在同一時(shí)刻安卓系統(tǒng)中僅存在一個(gè)該Activity實(shí)例赘艳,其它應(yīng)用復(fù)用該Activity實(shí)例
    啟動(dòng)該Activity時(shí)如果該Activity實(shí)例尚不存在會(huì)在新的任務(wù)棧中創(chuàng)建該Activity實(shí)例酌毡,如果該Activity實(shí)例已經(jīng)存在則直接顯示該Activity實(shí)例
    該Activity實(shí)例不與其它的Activity實(shí)例共存于同一個(gè)任務(wù)棧中,通過(guò)該Activity實(shí)例啟動(dòng)的其它Activity蕾管,只能在新的任務(wù)棧中創(chuàng)建實(shí)例枷踏。如果已經(jīng)存在與新啟動(dòng)的Activity的taskAffinity值相同的任務(wù)棧,則在該任務(wù)棧中創(chuàng)建新啟動(dòng)的Activity實(shí)例掰曾,否則就在一個(gè)新的任務(wù)棧中創(chuàng)建實(shí)例旭蠕。

三 LaunchMode與StartActivityForResult

在安卓開(kāi)發(fā)過(guò)程中我們常常使用startActivityForResult方法啟動(dòng)Activity并在onActivityResult方法中接收上個(gè)頁(yè)面返回的數(shù)據(jù),但你有可能遇到拿不到返回值的情況,可能是因?yàn)榇蜷_(kāi)的Activity的啟動(dòng)模式為singleTask掏熬。安卓5.0之后安卓的launchMode和onActivityResult發(fā)生了一些改變佑稠,假如Activity A 啟動(dòng)Activity B:
5.0以前
如果A的launchMode為singleInstance或者B的啟動(dòng)模式為singleTask或者singleInstance則A收不到返回?cái)?shù)據(jù);
5.0之后
不管A和B的啟動(dòng)模式是什么旗芬,A都可以收到B的返回?cái)?shù)據(jù)

四 通過(guò)設(shè)置intent的flag來(lái)設(shè)置啟動(dòng)模式

系統(tǒng)提供了兩種方式來(lái)設(shè)置啟動(dòng)模式讶坯,除了通過(guò)在Manifest.xml中設(shè)置還可以通過(guò)intent的Flag來(lái)設(shè)置,下面來(lái)介紹幾種Flag

  1. FLAG_ACTIVITY_NEW_TASK
    這個(gè)Flag是我們平時(shí)見(jiàn)的最多的岗屏,使用一個(gè)新的task來(lái)啟動(dòng)一個(gè)Activity辆琅。該flag通常使用在從Service啟動(dòng)Activity的場(chǎng)景,因?yàn)樵赟ervice中并不存在task这刷,所以該flag用來(lái)創(chuàng)建一個(gè)新的task并在該task中創(chuàng)建Activity實(shí)例婉烟。
  2. FLAG_ACTIVITY_SINGLE_TOP
    使用singletop模式啟動(dòng)一個(gè)Activity,與指定android:launchMode=“singleTop”效果相同暇屋。
  3. FLAG_ACTIVITY_CLEAR_TOP
    使用SingleTask模式來(lái)啟動(dòng)一個(gè)Activity似袁,與指定android:launchMode=“singleTask”效果相同。

Activity啟動(dòng)模式就介紹完了咐刨,在實(shí)際開(kāi)發(fā)過(guò)程中選擇合適的啟動(dòng)模式可以解決一些復(fù)雜的問(wèn)題昙衅,例如:某個(gè)頁(yè)面不能重復(fù)打開(kāi),我們就可以設(shè)置其啟動(dòng)模式為singleTask定鸟。在明白啟動(dòng)模式的基礎(chǔ)上我們可以根據(jù)具體需求來(lái)選擇啟動(dòng)模式而涉。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市联予,隨后出現(xiàn)的幾起案子啼县,更是在濱河造成了極大的恐慌,老刑警劉巖沸久,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件季眷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡卷胯,警方通過(guò)查閱死者的電腦和手機(jī)子刮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)窑睁,“玉大人挺峡,你說(shuō)我怎么就攤上這事÷盐浚” “怎么了沙郭?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)裳朋。 經(jīng)常有香客問(wèn)我病线,道長(zhǎng)吓著,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任送挑,我火速辦了婚禮绑莺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘惕耕。我一直安慰自己纺裁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布司澎。 她就那樣靜靜地躺著欺缘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪挤安。 梳的紋絲不亂的頭發(fā)上谚殊,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音蛤铜,去河邊找鬼嫩絮。 笑死,一個(gè)胖子當(dāng)著我的面吹牛围肥,可吹牛的內(nèi)容都是我干的剿干。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼穆刻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼置尔!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蛹批,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤撰洗,失蹤者是張志新(化名)和其女友劉穎篮愉,沒(méi)想到半個(gè)月后腐芍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡试躏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年猪勇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颠蕴。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泣刹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出犀被,到底是詐尸還是另有隱情椅您,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布寡键,位于F島的核電站掀泳,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜员舵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一脑沿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧马僻,春花似錦庄拇、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至女淑,卻和暖如春熄诡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诗力。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工凰浮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苇本。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓袜茧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親瓣窄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子笛厦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容