關(guān)于A(yíng)ctivity的啟動(dòng)模式

Activity的啟動(dòng)模式

Activity作為安卓四大組件之首擎颖,它的確非常重要,上篇文章我們介紹了Activity的生命周期观游,其實(shí)Activity的啟動(dòng)模式也是一個(gè)難點(diǎn)搂捧,有時(shí)為了項(xiàng)目的特殊需求,我們需要使用到Activity的啟動(dòng)模式懂缕,下面我們就具體的介紹Activity的啟動(dòng)模式和標(biāo)志位允跑。

1.1Activity的LaunchMode(啟動(dòng)模式)

首先我們開(kāi)介紹一下Activity為什么需要啟動(dòng)模式。在默認(rèn)情況下搪柑,多次啟動(dòng)同一個(gè)Activity聋丝,系統(tǒng)會(huì)創(chuàng)建多個(gè)實(shí)例,并把這些實(shí)例一一的壓入任務(wù)棧中工碾。當(dāng)我們單擊返回鍵的時(shí)候弱睦,就會(huì)一一回退。我們知道在數(shù)據(jù)結(jié)構(gòu)中渊额,棧是先進(jìn)后出的况木。其實(shí)就是每按一次返回鍵,銷(xiāo)毀一個(gè)Activity旬迹,就會(huì)有一個(gè)Activity實(shí)例出棧火惊,直到棧內(nèi)為空的時(shí)候,系統(tǒng)將任務(wù)棻伎眩回收矗晃。這就是Activity在默認(rèn)情況下的啟動(dòng)方式。在這里我們會(huì)不會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題:多次啟動(dòng)同一個(gè)Activity系統(tǒng)竟然多次創(chuàng)建實(shí)例宴倍,這是不是感覺(jué)很奇葩?在學(xué)習(xí)設(shè)計(jì)模式的時(shí)候,我們都知道有單實(shí)例模式仓技,我想Android系統(tǒng)也不會(huì)那么笨鸵贬。是的,Android系統(tǒng)其實(shí)早就知道這一點(diǎn)了脖捻,所以Android系統(tǒng)在設(shè)計(jì)的時(shí)候提供了啟動(dòng)模式來(lái)修改這種默認(rèn)的啟動(dòng)行為阔逼。目前有四種啟動(dòng)模式:standard、singleTop地沮、singleTask嗜浮、singleInstance羡亩。下面就對(duì)這四種啟動(dòng)模式進(jìn)行一一的介紹:

(1)standard

standard:標(biāo)準(zhǔn)模式,這是系統(tǒng)默認(rèn)的啟動(dòng)模式危融。每次啟動(dòng)一個(gè)Activity就會(huì)創(chuàng)建一個(gè)Activity的實(shí)例畏铆。不管這個(gè)實(shí)例是否存在都會(huì)進(jìn)行創(chuàng)建。每次創(chuàng)建Activity的生命周期吉殃,也都是符合正常情況下Activity的生命周期辞居。創(chuàng)建一個(gè)Activity實(shí)例,就會(huì)把這個(gè)實(shí)例壓入任務(wù)棧中蛋勺,一個(gè)任務(wù)椡咴睿可以有多個(gè)Activity實(shí)例,同一個(gè)Activity的各個(gè)實(shí)例也可以對(duì)應(yīng)不同的任務(wù)棧抱完。在標(biāo)準(zhǔn)模式下:一個(gè)Activity由誰(shuí)啟動(dòng)的贼陶,實(shí)例就會(huì)壓入啟動(dòng)者所在的任務(wù)棧,簡(jiǎn)單的說(shuō)就是:假如一個(gè)Activity A 啟動(dòng)了 Activity B 那么B的實(shí)例就會(huì)壓入A所在的任務(wù)棧中巧娱。在這我們提一點(diǎn)碉怔,不知道讀者是否遇到這樣一個(gè)問(wèn)題。使用ApplicationContext去啟動(dòng)一個(gè)Activity會(huì)報(bào)如下錯(cuò)誤:

接下來(lái)筆者將介紹如何重現(xiàn)這樣的錯(cuò)誤信息:

通過(guò)上面知道我們?nèi)绻肁ctivity A ?通過(guò)標(biāo)準(zhǔn)模式去啟動(dòng)Activity B ?B的實(shí)例會(huì)壓入A的實(shí)例所在的任務(wù)棧中家卖。這個(gè)很容易理解眨层。這里介紹的都是通過(guò)Activity去啟動(dòng)另一個(gè)Activity是沒(méi)問(wèn)題的,因?yàn)锳ctivity啟動(dòng)者會(huì)有對(duì)應(yīng)的任務(wù)棧上荡。假如我們通過(guò)廣播接受者去啟動(dòng)一個(gè)Activity呢?如下圖所示:

通過(guò)標(biāo)準(zhǔn)模式趴樱,以上的代碼能啟動(dòng)一個(gè)Activity嗎,還是會(huì)報(bào)上面所說(shuō)的錯(cuò)誤酪捡?筆者告訴大家叁征,答案是:

《1》當(dāng)這個(gè)廣播接收者是通過(guò)手動(dòng)在A(yíng)ctivity ?A 中注冊(cè)的情況下是可以的,上面代碼中的Context屬于A(yíng)ctivity A 對(duì)象逛薇,這個(gè)時(shí)候通過(guò)啟動(dòng) Activity B其實(shí)就是通過(guò)這個(gè)Activity A 啟動(dòng)的捺疼,B的實(shí)例就會(huì)壓入到Activity B 實(shí)例所在的任務(wù)棧。這樣不會(huì)報(bào)錯(cuò)永罚,正常啟動(dòng)啤呼。

《2》當(dāng)這個(gè)廣播接收者是通過(guò)在Manifest中注冊(cè)的情況下是不可的,就會(huì)報(bào)上面所說(shuō)的錯(cuò)誤信息呢袱。這個(gè)時(shí)候上面代碼

中的Context是屬于ReceiverRestrictedContext@41a7c2b8廣播接受者的官扣,廣播接受者沒(méi)有對(duì)應(yīng)的任務(wù)棧,因此不能通過(guò)context去啟動(dòng)一個(gè)Activity羞福。當(dāng)然假如一定要啟動(dòng)Activity也是可以的惕蹄,我們可以進(jìn)行設(shè)置標(biāo)志位:FLAG_ACTIVITY_NEW_TASK。其實(shí)就是啟動(dòng)一個(gè)新的任務(wù)棧,把啟動(dòng)的Activity壓入這個(gè)新的任務(wù)棧中卖陵。其實(shí)這種啟動(dòng)模式遭顶,就是下面會(huì)介紹的另一種啟動(dòng)模式:sinleTask啟動(dòng)模式

(2)singleTop

singleTop:棧頂復(fù)用模式。同樣用例子說(shuō)明:當(dāng)前任務(wù)棧里的情況是A B C D ,A位于棧頂泪蔫,C位于棧底棒旗。

《1》通過(guò)singleTop模式Activity D啟動(dòng)Activity A,這個(gè)時(shí)候不會(huì)創(chuàng)建A的實(shí)例鸥滨,只是繼續(xù)使用棧頂中的A嗦哆,調(diào)用了onNewInstane方法,通過(guò)此方法的參數(shù)婿滓,我們可以取出當(dāng)前請(qǐng)求的數(shù)據(jù)老速。既然不會(huì)重新創(chuàng)建A,所以A的生命周期方法:onCreate、onStart凸主、onResume方法不會(huì)被調(diào)用橘券。這個(gè)時(shí)候棧內(nèi)的情況是:A B C D。

《2》同樣通過(guò)singleTop模式Activity D啟動(dòng)Activity B 卿吐,由于B不在棧頂旁舰,這個(gè)時(shí)候會(huì)創(chuàng)建B的實(shí)例,開(kāi)始B的生命周期方法嗡官。棧內(nèi)情況:B A B C D,這個(gè)應(yīng)該很容易理解箭窜,筆者在這就不多說(shuō)了。

(3)singleTask

singleTask:棧內(nèi)復(fù)用模式衍腥。通過(guò)棧頂復(fù)用模式的學(xué)習(xí)磺樱,我想學(xué)習(xí)棧內(nèi)復(fù)用模式應(yīng)該會(huì)比較容易的理解。這是一種單實(shí)例模式婆咸,在這種情況下竹捉,如果通過(guò)singleTask模式去啟動(dòng)一個(gè)Activity A,首先系統(tǒng)會(huì)尋找是否存在A(yíng)所需要的任務(wù)棧尚骄,如果不存在块差,則創(chuàng)建任務(wù)棧,再創(chuàng)建A的實(shí)例壓入任務(wù)棧中倔丈。如果存在憨闰,則檢查棧中是否存在A(yíng)的實(shí)例,如果不存在需五,創(chuàng)建A的實(shí)例壓入棧中起趾。如果存在,則把A移動(dòng)到棧頂警儒,假如之前棧內(nèi)之前的情況是 D C B A ,D位于棧頂,這個(gè)時(shí)候把A移到棧頂蜀铲,由于singleTask具有clearTop效果边琉,會(huì)導(dǎo)致A 上面的全部出棧,所以把A移到棧頂之后棧內(nèi)的情況是A记劝。下面用例子來(lái)說(shuō)明:

《1》棧S1 的情況是 A B C, A位于棧頂变姨。創(chuàng)建D,并且所需的任務(wù)棧是S2。這個(gè)時(shí)候棧S2和實(shí)例均不存在厌丑,則需要?jiǎng)?chuàng)建任務(wù)棧S2和D實(shí)例定欧,把D實(shí)例壓入S2中。

《2》假如創(chuàng)建D所需的棧是S1,這個(gè)時(shí)候怒竿,直接創(chuàng)建D實(shí)例砍鸠,壓入S1中。S1的情況是:D A B C

《3》假如S1的情況是 A B C D 耕驰,創(chuàng)建D所需的任務(wù)棧是S1爷辱,這個(gè)時(shí)候S1已經(jīng)存在,D也存在朦肘。所以直接把D移到棧頂饭弓,最后由于clearTop模式,S1的情況是A

(4)singleInstance

singleInstance:單實(shí)例模式,這種模式具有singleTask模式所有的特性媒抠。和singleTask不同的是弟断,通過(guò)singleInstance模式啟動(dòng)的Activity所在的任務(wù)棧只能有一個(gè)實(shí)例。而通過(guò)singleTask啟動(dòng)的Activity所在任務(wù)椗可可以有不同的實(shí)例阀趴,只是同一個(gè)Activity只能有一個(gè)實(shí)例。

Activity的Flag(標(biāo)志位)

在上面介紹Activity的啟動(dòng)模式的時(shí)候冲秽,我們?cè)?jīng)提到舍咖,假如通過(guò)ApplicationContext去啟動(dòng)一個(gè)Activity是不行的。會(huì)報(bào):

AndroidRuntimeException: Calling startActivity() from outside of an Activity锉桑,Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

錯(cuò)誤的信息就是需要一個(gè)標(biāo)志位的意思排霉。

下面我們就介紹一下標(biāo)志位:標(biāo)志位有很多,這里主要分析一下比較常用的標(biāo)志位民轴。有的標(biāo)志位可以設(shè)置Activity的啟動(dòng)模式攻柠。有的標(biāo)志位可以影響Activity 的運(yùn)行狀態(tài)。大部分情況下我們不需要去指定標(biāo)志位后裸,對(duì)標(biāo)志位理解即可瑰钮。

(1)FLAG_ACTIVITY_NEW_TASK

該標(biāo)志位的作用是設(shè)置Activity的啟動(dòng)模式是singleTask 即棧內(nèi)復(fù)用模式。

(2)FLAG_ACTIVITY_SINGLE_TOP

該標(biāo)志位的作用是設(shè)置Activity的啟動(dòng)模式是singleTop模式 即單實(shí)例模式

(3)FLAG_ACTIVITY_CLEAR_TOP

該標(biāo)志位的作用是啟動(dòng)一個(gè)Activity微驶,該Activty實(shí)例所在的任務(wù)棧中所有在該實(shí)例之上的實(shí)例都要出棧浪谴。本身singleTop啟動(dòng)模式就具有該clearTop特性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末开睡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子苟耻,更是在濱河造成了極大的恐慌篇恒,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凶杖,死亡現(xiàn)場(chǎng)離奇詭異胁艰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)智蝠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)腾么,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人杈湾,你說(shuō)我怎么就攤上這事解虱。” “怎么了毛秘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵饭寺,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我叫挟,道長(zhǎng)艰匙,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任抹恳,我火速辦了婚禮员凝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奋献。我一直安慰自己健霹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布瓶蚂。 她就那樣靜靜地躺著糖埋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窃这。 梳的紋絲不亂的頭發(fā)上瞳别,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音杭攻,去河邊找鬼祟敛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛兆解,可吹牛的內(nèi)容都是我干的馆铁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锅睛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼埠巨!你這毒婦竟也來(lái)了历谍?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辣垒,失蹤者是張志新(化名)和其女友劉穎伐庭,沒(méi)想到半個(gè)月后烤镐,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柳譬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年扛点,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哥遮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡陵究,死狀恐怖眠饮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铜邮,我是刑警寧澤仪召,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站松蒜,受9級(jí)特大地震影響扔茅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秸苗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一召娜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惊楼,春花似錦玖瘸、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至弧可,卻和暖如春蔑匣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侣诺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工殖演, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人年鸳。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓趴久,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親搔确。 傳聞我的和親對(duì)象是個(gè)殘疾皇子彼棍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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