關(guān)于Activity棧的簡(jiǎn)單總結(jié)

? 前兩天在寫項(xiàng)目的時(shí)候突然碰到個(gè)問(wèn)題宴卖,當(dāng)用戶進(jìn)入應(yīng)用時(shí),先進(jìn)入MainActivity衔峰,如果判斷為非登陸狀態(tài)佩脊,則應(yīng)該直接跳轉(zhuǎn)到登陸頁(yè)面 ,如果在登陸界面放棄登陸垫卤,則應(yīng)該直接回到主界面威彰。這意味著在登陸界面打開(kāi)時(shí),MainActivity應(yīng)該從回退棧中彈出穴肘,而不是下壓歇盼。那個(gè)時(shí)候草草百度了一番,用Intent加Flag的方法匆匆混了過(guò)去评抚,然而新棧建立的Transition動(dòng)畫著實(shí)讓人難受(所以又回去補(bǔ)了一波動(dòng)畫的相關(guān)豹缀,然而還是沒(méi)有補(bǔ)到Activity Transition的部分-_-),今天完善各個(gè)界面的邏輯和細(xì)節(jié)的時(shí)候又想起來(lái)了這檔子事慨代,于是拋下寫到一半的代碼邢笙,準(zhǔn)備溫習(xí)一下Activity進(jìn)棧出棧的具體過(guò)程。又逮著碼字的機(jī)會(huì)了了J坛住氮惯!

? Activity的出入棧控制主要來(lái)自于兩個(gè)地方Activity的聲明處——Manifest文件定義的屬性和Activity的開(kāi)啟者——Intent的Flag定義。下面分別看看它們都能定義哪些屬性筐骇。

Manifest

? Manifest中關(guān)于Activity棧的控制债鸡,大多數(shù)人最先接觸到的大概就是android:launchMode的四個(gè)屬性:standard、singleTop铛纬、singleTask和singleInstance厌均,它們的意義如下:

1.standard
    Activity的默認(rèn)啟動(dòng)模式,在任何情況下都直接將一個(gè)新的Activity實(shí)例入棧告唆。
2.singleTop
    常用的Activity啟動(dòng)模式棺弊,當(dāng)要開(kāi)啟的Activity已在棧頂時(shí),不創(chuàng)建新的實(shí)例擒悬,但調(diào)用onNewIntent方法模她;不在棧頂時(shí),創(chuàng)建新的實(shí)例懂牧。
3.singleTask
    當(dāng)Activity為該啟動(dòng)模式時(shí)侈净,會(huì)先在棧中查找是否存在該Activity實(shí)例,沒(méi)有的話會(huì)新建一個(gè)實(shí)例僧凤,這個(gè)實(shí)例所在的棧與taskAffinity屬性有關(guān)畜侦;如果當(dāng)前棧中存在該Activity實(shí)例的話,則會(huì)將該實(shí)例送到棧頂躯保,并且將其之前所有的Activity全部彈出旋膳。
4.singleInstance
    當(dāng)Activity為該模式時(shí),該Activity實(shí)例會(huì)有一個(gè)獨(dú)立的棧途事,并且該棧中只會(huì)有這一個(gè)實(shí)例验懊,所有跳轉(zhuǎn)到這個(gè)Activity的進(jìn)程都會(huì)共享這一個(gè)實(shí)例。當(dāng)從這個(gè)棧切換到別的Activity時(shí)尸变,會(huì)將新的Activity壓入Activity啟動(dòng)前的棧中义图,此時(shí)再返回就會(huì)跳過(guò)這個(gè)singleInstance的Activity而回到開(kāi)始的棧。

有兩個(gè)需要注意的點(diǎn)召烂,一是被singleTask標(biāo)注的Activity已在別的進(jìn)程的Task中存在且處于棧頂時(shí)碱工,就不會(huì)在Activity調(diào)用進(jìn)程創(chuàng)建一個(gè)新實(shí)例,而是將后臺(tái)進(jìn)程的Task棧內(nèi)容壓入當(dāng)前Task棧骑晶,如下圖所示:

pic1.png

二是Android的棧彈出策略:在當(dāng)前Task中的Activity實(shí)例已全部彈出痛垛,就會(huì)回到該Task的上一個(gè)棧,而不是直接退回到主界面(也是因?yàn)檫@個(gè)原因讓我把LoginActivity設(shè)置為singleTask從而建一個(gè)新棧桶蛔,在onBackPress時(shí)直接回到主界面的想法落空了)匙头。

除了launchMode管控的Activity啟動(dòng)策略之外Activity還有下面幾個(gè)與返回棧相關(guān)的屬性:

android:taskAffinity = "string"
    其值默認(rèn)為當(dāng)前包名,用于標(biāo)識(shí)無(wú)歸屬Activity的歸屬任務(wù)仔雷。這里的無(wú)歸屬Activity指以設(shè)置了Flag為FLAG_ACTIVITY_NEW_TASK的Intent打開(kāi)的Activity 蹂析,或者是launchMode為singleTask而當(dāng)前Task中無(wú)其實(shí)例需要新建一個(gè)實(shí)例的Activity舔示。它能夠指定上述Activity所屬的Task,或者說(shuō)設(shè)定其親緣關(guān)系电抚。這個(gè)屬性設(shè)置可以達(dá)到創(chuàng)建多個(gè)棧并改變其退出順序的效果(比如實(shí)現(xiàn)以為不可能實(shí)現(xiàn)的退出MainActivity而不退出應(yīng)用)
    
android:allowTaskReparenting = [true|false]
    其值表示是否允許將標(biāo)注的Activity在當(dāng)前Task轉(zhuǎn)入后臺(tái)時(shí)改變其所處Task惕稻,而歸屬到taskAffinity標(biāo)注的Task中去,僅對(duì)launchMode為standard與singleTop的Activity有效蝙叛,默認(rèn)為false俺祠。一個(gè)具體的例子就是當(dāng)我們的應(yīng)用調(diào)用了一個(gè)外部瀏覽器時(shí),當(dāng)該屬性為true借帘,則打開(kāi)的web頁(yè)面將歸屬于瀏覽器蜘渣,此時(shí)退出瀏覽器后會(huì)直接回到主界面;反之肺然,該屬性為false時(shí)蔫缸,退出瀏覽器界面后將會(huì)回到原來(lái)的應(yīng)用界面。
    
android:clearTaskOnLaunch=["true" | "false"]
    其值表示home鍵返回桌面又從桌面再次打開(kāi)應(yīng)用時(shí)际起,是否清除棧底以外的所有Activity(注意拾碌,因?yàn)長(zhǎng)auncher入口只有一個(gè),所以這里的棧指的就是MainActivity棧街望,其他棧不受影響)校翔。
    
android:alwaysRetainTaskState=["true" | "false"]
    其值表示是否允許始終保持Task的狀態(tài)(系統(tǒng)一般會(huì)在應(yīng)用無(wú)響應(yīng)半小時(shí)后清除根Activity之外的所有Activity)。
    
android:finishOnTaskLaunch=["true" | "false"]
    當(dāng)該值為true時(shí)它匕,標(biāo)記的Activity在棧頂展融,且應(yīng)用此時(shí)從桌面被啟動(dòng)時(shí)窖认,該Activity將被finish豫柬,(但當(dāng)Activity為根Activity時(shí)失效)。

更多相關(guān)的屬性扑浸,參見(jiàn)官方文檔:<activity>標(biāo)簽


Intent

? Intent作為Android四大組件的溝通橋梁烧给,用Action確定了響應(yīng)對(duì)象,用Category規(guī)定了響應(yīng)條件喝噪,用Data描述了請(qǐng)求數(shù)據(jù)類型础嫡,至于開(kāi)啟新組件的屬性和模式,則交給了Flag酝惧。下面是列舉出來(lái)的幾個(gè)Flag:

FLAG_ACTIVITY_NEW_TASK
    根據(jù)親緣關(guān)系開(kāi)啟一個(gè)Activity榴鼎,若此時(shí)存在與其有親緣關(guān)系的棧,則在該棧中開(kāi)啟Activity,開(kāi)啟方式受launchMode約束;否則創(chuàng)建一個(gè)新棧谋减。與FLAG_ACTIVITY_MULTIPLE_TASK一起使用時(shí)贰剥,無(wú)論如何都會(huì)創(chuàng)建一個(gè)新棧。
    
FLAG_ACTIVITY_CLEAR_TOP
    類似singleTask模式弟蚀,在開(kāi)啟已存在棧中的Activity實(shí)例時(shí)脚曾,將其推至棧頂唐全,并將其上的Activity全部出棧闽瓢,但此時(shí)“推至棧頂”這個(gè)過(guò)程實(shí)際上是連已存在的相關(guān)Activity實(shí)例也一并彈出棧接癌,而重新創(chuàng)建一個(gè)Activity實(shí)例,而不是調(diào)用NewIntent.
    
FLAG_ACTIVITY_CLEAR_TASK
    在目標(biāo)Activity打開(kāi)前清除其所在棧內(nèi)的Activity實(shí)例扣讼,必須與FLAG_ACTIVITY_NEW_TASK一起用缺猛。
    
FLAG_ACTIVITY_SINGLE_TOP
    效果同singleTop.
    
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 
    由此標(biāo)志開(kāi)啟的Activity所處棧不會(huì)出現(xiàn)在Recent界面,該Activity需要是這個(gè)棧的根Activity椭符,其效果與activity=excludeFromRecents = "true"一致枯夜。

FLAG_ACTIVITY_TASK_ON_HOME 
    由此標(biāo)識(shí)開(kāi)啟的Activity所處棧將會(huì)直接置于Home所處棧之上,也就是onBackPress時(shí)會(huì)直接退出到主界面艰山。此標(biāo)識(shí)需要同F(xiàn)LAG_ACTIVITY_NEW_TASK一同使用湖雹,并且必須保證其開(kāi)啟了一個(gè)新棧。

FLAG_ACTIVITY_NO_ANIMATION
    取消Activity的Transition效果曙搬。

更多的Flag參見(jiàn):Intent

最后

講道理其實(shí)Activity的棧操作還是挺麻煩的一件事摔吏,還有很多屬性都沒(méi)有列舉出來(lái),以及startActivityForResult的一些特殊情況也并沒(méi)有總結(jié)纵装,關(guān)愛(ài)懶癌晚期患者征讲。不過(guò)上面的在正常情況下應(yīng)該是夠用了,一般的場(chǎng)景也不會(huì)太多的去關(guān)注onBackPress會(huì)返回到什么界面(至今看到同應(yīng)用多棧操作的貌似也就系統(tǒng)的Setting和WPS的多任務(wù)閱讀)橡娄,實(shí)在不行反正鏈接就在那诗箍,隨時(shí)可以回去翻,就這樣吧~

如果上面的內(nèi)容有任何錯(cuò)誤或不足挽唉,歡迎各種交流指導(dǎo)滤祖,鞠躬。
個(gè)人Github主頁(yè):Lazxy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瓶籽,一起剝皮案震驚了整個(gè)濱河市匠童,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌塑顺,老刑警劉巖汤求,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異严拒,居然都是意外死亡扬绪,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門裤唠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挤牛,“玉大人,你說(shuō)我怎么就攤上這事巧骚∩薜撸” “怎么了格二?”我有些...
    開(kāi)封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)竣蹦。 經(jīng)常有香客問(wèn)我顶猜,道長(zhǎng),這世上最難降的妖魔是什么痘括? 我笑而不...
    開(kāi)封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任长窄,我火速辦了婚禮,結(jié)果婚禮上纲菌,老公的妹妹穿的比我還像新娘挠日。我一直安慰自己,他們只是感情好翰舌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布嚣潜。 她就那樣靜靜地躺著,像睡著了一般椅贱。 火紅的嫁衣襯著肌膚如雪懂算。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天庇麦,我揣著相機(jī)與錄音计技,去河邊找鬼。 笑死山橄,一個(gè)胖子當(dāng)著我的面吹牛垮媒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播航棱,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼睡雇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了丧诺?” 一聲冷哼從身側(cè)響起入桂,我...
    開(kāi)封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤奄薇,失蹤者是張志新(化名)和其女友劉穎驳阎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體馁蒂,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呵晚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了沫屡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饵隙。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沮脖,靈堂內(nèi)的尸體忽然破棺而出金矛,到底是詐尸還是另有隱情芯急,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布驶俊,位于F島的核電站娶耍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏饼酿。R本人自食惡果不足惜榕酒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望故俐。 院中可真熱鬧想鹰,春花似錦、人聲如沸药版。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)槽片。三九已至惩妇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筐乳,已是汗流浹背歌殃。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蝙云,地道東北人氓皱。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像勃刨,于是被迫代替她去往敵國(guó)和親波材。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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