Activity 知識(shí)梳理(2) - Activity 棧

一漠趁、AndroidManifest.xml中指定launchMode

1.1standard

標(biāo)準(zhǔn)模式,每次啟動(dòng)Activity都會(huì)創(chuàng)建一個(gè)新的Activity實(shí)例酥艳,并且將其壓入任務(wù)棧棧頂,而不管這個(gè) Activity 是否已經(jīng)存在,都會(huì)執(zhí)行onCreate() ->onStart() -> onResume澡屡。

1.2 singleTop

棧頂復(fù)用模式,如果新Activity已經(jīng)位于棧頂咐旧,那么此Activity不會(huì)被重新創(chuàng)建驶鹉,同時(shí)ActivityonNewIntent方法會(huì)被回調(diào),如果Activity已經(jīng)存在但是不再棧頂铣墨,那么和standard模式一樣室埋。
如果Activity當(dāng)前是onResume狀態(tài),那么調(diào)用后會(huì)執(zhí)行onPause() -> onNewIntent() -> onResume()伊约。

1.3 singleTask

棧內(nèi)復(fù)用模式姚淆,創(chuàng)建這樣的Activity,系統(tǒng)會(huì)確認(rèn)它所需任務(wù)棧是否已經(jīng)創(chuàng)建屡律,否則先創(chuàng)建任務(wù)棧腌逢,然后放入Activity如果棧中已經(jīng)有一個(gè)Activity實(shí)例疹尾,那么會(huì)做兩件事:

  • 這個(gè)Activity會(huì)回到棧頂執(zhí)行onNewIntent
  • 清理在當(dāng)前Activity上面的所有Activity

上面的如果棧中已經(jīng)有一個(gè)Activity實(shí)例上忍,這個(gè)判斷條件的標(biāo)準(zhǔn)是由android:taskAffinity決定的骤肛,下面我們做一個(gè)簡(jiǎn)單的對(duì)比:

  • 第一種情況纳本,不給singleTaskActivity設(shè)置taskAffinity窍蓝,這時(shí)默認(rèn)情況下屬于同一個(gè)Application的所有Activity具有的taskAffinity是相同的,就是我們?cè)?code>AndroidManifest中指定的packageName
<activity android:name=".SingleTaskActivity" android:launchMode="singleTask"/>

這時(shí)候我們從MainActivity啟動(dòng)SingleTaskActivity后繁成,任務(wù)棧的情況是吓笙,MainActivitySingleTaskActivity處于同一個(gè)Task當(dāng)中:


我們看到SingleTaskActivityMainActivity位于同一個(gè)棧中,因此singleTask并不是讓這個(gè)Activity獨(dú)占一個(gè)Task巾腕。

  • 第二種情況面睛,給singleTaskActivity設(shè)置affinity
<activity android:name=".SingleTaskActivity" android:launchMode="singleTask" android:taskAffinity="com.android.singleTask"/>

此時(shí)進(jìn)行同樣的操作,任務(wù)棧的情況變?yōu)椋?br>


我們?cè)?code>SingleTaskActivity的界面按下 Home鍵尊搬,再點(diǎn)擊圖標(biāo)進(jìn)入MainActivity叁鉴,可以看到當(dāng)前應(yīng)用有兩個(gè)棧:


此時(shí),我們?cè)冱c(diǎn)擊按鈕啟動(dòng)SingleTaskActivity佛寿,那么會(huì)執(zhí)行

MainActivity#onPause
SingleTaskActivity#onNewIntent 
SingleTaskActivity#onRestart 
SingleTaskActivity#onStart 
SingleTaskActivity#onResume
MainActivity#onStop

這是由于當(dāng)啟動(dòng)SingleTaskActivity幌墓,系統(tǒng)去尋找該SingleTaskActivity所對(duì)應(yīng)的棧是否存在,而這時(shí)候是存在的冀泻,也就上面看到TaskRecord[cd9ca5d]常侣,所以它不會(huì)創(chuàng)建新的SingleTaskActivity,而是復(fù)用這個(gè)棧中的Activity弹渔,而由于這個(gè)Activity又位于棧頂胳施,因此它的表現(xiàn)和SingleTop相同。

  • 第三種情況肢专,我們?cè)囍诘诙N的基礎(chǔ)上再加大一些難度舞肆, 在SingleTaskActivity所在的Task上再加一個(gè) SingleTaskAboveActivity,首先我們從MainAcitivity -> SingleTaskActivity -> SingleTaskAboveActvity
<activity android:name=".SingleTaskAboveActivity"/>

這一流程過后博杖,棧的結(jié)構(gòu)為椿胯,可以看到SingleTaskActivitySingleTaskAboveActvity位于同一棧中(雖然我們并沒有聲明SingleTaskAboveActivitytaskAffinitycom.android.singleTask):


SingleTaskAboveActvity界面,按Home退到后臺(tái)之后重新進(jìn)入欧募,棧的結(jié)構(gòu)不變压状,只不過當(dāng)前可見的是 MainActivity,這時(shí)我們?cè)俅螄L試啟動(dòng)SingleTaskActivity跟继,那么會(huì)依次調(diào)用:

MainActivity#onPause
SingleTaskAboveActivity#onDestroy
SingleTaskActivity#onNewIntent
SingleTaskActivity#onRestart
SingleTaskActivity#onStart
SingleTaskActivity#onResume
MainActivity#onStop

而棧的結(jié)構(gòu)變?yōu)槿缦拢?br>


和第二種情況類似种冬,當(dāng)啟動(dòng)SingleTaskActivity時(shí),系統(tǒng)去尋找該SingleTaskActivity所對(duì)應(yīng)的棧是否存在舔糖,而這時(shí)候是存在的娱两,也就上面看到TaskRecord[a3771ca],所以它不會(huì)創(chuàng)建新的SingleTaskActivity金吗,而是復(fù)用這個(gè)棧中的SingleTaskActivity十兢,但此時(shí)SingleTaskActivity并不位于棧頂趣竣,在它上面還有一個(gè)SingleTaskAboveActivity,因此會(huì)把SingleTaskAboveActivity先出棧旱物,再復(fù)用原先位于這個(gè)棧中的SingleTaskActivity實(shí)例遥缕。

1.4 singleInstance

這種模式的Activity只能單獨(dú)位于一個(gè)任務(wù)棧內(nèi),由于棧內(nèi)的復(fù)用特性宵呛,后續(xù)請(qǐng)求均不會(huì)創(chuàng)建新的Activity单匣,除非這個(gè)獨(dú)特的任務(wù)棧被系統(tǒng)銷毀了。

  • 第一種情況宝穗,先看最簡(jiǎn)單的户秤,我們新建一個(gè)SingleInstanceActivity
<activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance"/>

我們從MainAcitivity啟動(dòng)它,此時(shí)任務(wù)棧的情況是逮矛,他們位于不同的Task中鸡号,符合我們的預(yù)期:

  • 第二種情況,此時(shí)按Home回到桌面须鼎,再重新點(diǎn)圖標(biāo)進(jìn)入MainActivity鲸伴,任務(wù)棧依然是兩個(gè),我們此時(shí)再啟動(dòng)SingleInstanceActivity
MainActivity#onPause
SingleInstanceActivity#onNewIntent 
SingleInstanceActivity#onRestart 
SingleInstanceActivity#onStart 
SingleInstanceActivity#onResume
MainActivity#onStop

和啟動(dòng)在另一個(gè)棧中已存在的singleTaskAcitivity的情況是類似的莉兰。

  • 第三種情況挑围,我們?cè)倏匆幌拢?code>affinity對(duì)于singleInstance會(huì)不會(huì)有影響呢,我們定義兩個(gè)affinity相同的 singleInstance
 <activity android:name=".SingleInstanceActivity" android:launchMode="singleInstance" android:taskAffinity="com.android.singleInstance"/>
<activity android:name=".SingleInstanceActivityAnother" android:launchMode="singleInstance" android:taskAffinity="com.android.singleInstance"/>

我們先從MainActivity啟動(dòng)SingleInstanceActivity糖荒,按Home回到桌面再進(jìn)入杉辙,此時(shí)Task的情況和上面相同的,那么這時(shí)候我們啟動(dòng)SingleInstanceActivityAnother

singleInstance_another.png

可以看到捶朵,它并沒有受到affinity的影響蜘矢,而是重新起了一個(gè)新的棧。

二综看、在Intent當(dāng)中指定啟動(dòng)模式

2.1 FLAG_ACTIVITY_NEW_TASK

singleTask行為相同品腹,前面已經(jīng)詳細(xì)分析過了,這里需要注意 affinity 的聲明红碑。

2.2 FLAG_ACTIVITY_SINGLE_TOP

singleTop行為相同舞吭,比較簡(jiǎn)單,就不舉例子了析珊。

2.3 FLAG_ACTIVITY_CLEAR_TASK

FLAG_ACTIVITY_NEW_TASK 何用羡鸥,這個(gè)Activity會(huì)新起一個(gè)棧,原來?xiàng)1磺蹇罩已埃瑮V械?code>Activity也被銷毀惧浴。

2.5 FLAG_ACTIVITY_CLEAR_TOP

會(huì)清除這個(gè)Activity之上所有的Activity,我們來試一下奕剃,新建兩個(gè)新的SecondActivityThirdActivity衷旅,從Main -> Second -> Third捐腿,此時(shí)棧的結(jié)構(gòu)是:

clearTop_1.png

此時(shí),我們按如下方式啟動(dòng)SecondActivity

    public void third(View view) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);
    }

這之后柿顶,棧的結(jié)構(gòu)變?yōu)椋?code>ThirdAcitivity被出棧了:

clearTop_2.png

2.6 FLAG_ACTIVITY_REORDER_TO_FRONT

上面的FLAG_ACTIVITY_CLEAR_TOP是把位于目標(biāo)Activity之上的Activity都銷毀茄袖,而則個(gè)FLAG則是對(duì)棧重新排序,把目標(biāo)Activity移到最前臺(tái)九串,其它的位置不變绞佩,我們?cè)谇耙环N的基礎(chǔ)上寺鸥,在ThirdActivity中換一種方式來啟動(dòng)SecondActivity

    public void third(View view) {
        Intent intent = new Intent(this, SecondActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        startActivity(intent);
    }

這回猪钮,最終棧的結(jié)構(gòu)變?yōu)榱耍梢钥吹?code>ThirdActivity并沒有被出棧:

Paste_Image.png

三胆建、AndroidManifest中的屬性

3.1 alwaysRetainTaskState

這個(gè)標(biāo)志只對(duì)根Activity有用烤低,默認(rèn)情況下,當(dāng)我們的應(yīng)用在后臺(tái)一段時(shí)間笆载,它會(huì)銷毀該Task除了根以外的所有Activity扑馁,如果我們希望保持這個(gè)Task的原有狀態(tài),那么給這個(gè)Task的根Activity設(shè)置這個(gè)屬性凉驻,默認(rèn)值是false腻要。

3.2 clearTaskOnLaunch

從桌面啟動(dòng)該Activity的時(shí)候會(huì)清空該Task除了根Activity外的所有Activity,我們從Main -> Second -> Third涝登,此時(shí)棧內(nèi)有3個(gè)Activity雄家,按Home回到桌面后,點(diǎn)圖標(biāo)重新進(jìn)入胀滚,此時(shí)Task只剩下根Activity 了:

Paste_Image.png

3.3 finishOnTaskLaunch

這個(gè)和上面類似趟济,但是它對(duì)根Activity無效,我們給SecondActivity設(shè)置這個(gè)屬性咽笼,先啟動(dòng)到ThirdActivity顷编,這時(shí)候棧的結(jié)構(gòu)為:

Paste_Image.png

接著,我們按Home回到桌面剑刑,點(diǎn)圖標(biāo)重新進(jìn)入媳纬,棧的結(jié)構(gòu)變?yōu)橄旅孢@樣,可以看到SecondActivity沒有了:

Paste_Image.png

3.4 noHistory

Activity在不可見之后施掏,不保存記錄

  • 第一種情況钮惠,我們給SecondActivity設(shè)置這個(gè)屬性,接著從Main -> Second -> Third其监,然后按Back返回萌腿,此時(shí)的生命周期為:
ThirdActivity#onPause
MainActivity#onRestart
MainActivity#onStart
MainActivity#onResume
SecondActivity#onDestroy
ThirdActivity#onStop
ThirdActivity#onDestroy
  • 第二種情況,如果我們?cè)?code>ThirdActivity時(shí)抖苦,不是按Back毁菱,而是按Home到桌面米死,會(huì)調(diào)用:
ThirdActivity#onPause
SecondActivity#onDestroy
ThirdActivity#onStop
  • 第三種情況,我們給根MainAcitivity設(shè)置這個(gè)屬性贮庞,啟動(dòng)它后退出:
MainActivity#onCreate
MainActivity#onStart
MainActivity#onResume
MainActivity#onDestory
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末峦筒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子窗慎,更是在濱河造成了極大的恐慌物喷,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遮斥,死亡現(xiàn)場(chǎng)離奇詭異峦失,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)术吗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門尉辑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人较屿,你說我怎么就攤上這事隧魄。” “怎么了隘蝎?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵购啄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我嘱么,道長(zhǎng)狮含,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任拱撵,我火速辦了婚禮辉川,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拴测。我一直安慰自己乓旗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布集索。 她就那樣靜靜地躺著屿愚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪务荆。 梳的紋絲不亂的頭發(fā)上妆距,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音函匕,去河邊找鬼娱据。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盅惜,可吹牛的內(nèi)容都是我干的中剩。 我是一名探鬼主播忌穿,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼结啼!你這毒婦竟也來了掠剑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤郊愧,失蹤者是張志新(化名)和其女友劉穎朴译,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體属铁,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眠寿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了红选。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澜公。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骇两,死狀恐怖污尉,靈堂內(nèi)的尸體忽然破棺而出胯甩,到底是詐尸還是另有隱情,我是刑警寧澤蝶防,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站明吩,受9級(jí)特大地震影響间学,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜印荔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一低葫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仍律,春花似錦嘿悬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至草则,卻和暖如春钢拧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背炕横。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工源内, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人份殿。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓膜钓,卻偏偏與公主長(zhǎng)得像塔鳍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子呻此,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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