深入理解Activity啟動(dòng)模式之大結(jié)局

lastday.jpg

談起Activity的啟動(dòng)模式必不可少的要是launchMode剩膘、Flags、taskAffinity這三塊知識(shí)點(diǎn)酵幕,上一篇文章 深入理解Activity啟動(dòng)模式之launchMode 看過(guò)的同學(xué)都知道該文章對(duì)launchMode做了非常詳細(xì)的講解记餐,所以本片文章承接上一篇文章對(duì)剩余的Flags剑勾、taskAffinity這兩塊做講述,希望看完此片文章的同學(xué)們此后遇到Activity的啟動(dòng)模式相關(guān)問(wèn)題或使用場(chǎng)景再也不用查資料_瞬铸。
(PS:本篇文章的實(shí)驗(yàn)數(shù)據(jù)都基于Android7.0)

Activity啟動(dòng)模式之Flags

先來(lái)看看常用Flags:

  • Intent.FLAG_ACTIVITY_SINGLE_TOP
    ??該標(biāo)志位表示使用singleTop模式來(lái)啟動(dòng)一個(gè)Activity而钞,與在清單文件指定android:launchMode="singleTop"效果相同。
  • Intent.FLAG_ACTIVITY_CLEAR_TOP
    ??該標(biāo)志位表示使用singleTask模式來(lái)啟動(dòng)一個(gè)Activity翎猛,與在清單文件指定android:launchMode="singleTask"效果相同胖翰。
  • Intent.FLAG_ACTIVITY_NO_HISTORY
    ??使用該模式來(lái)啟動(dòng)Activity,當(dāng)該Activity啟動(dòng)其他Activity后切厘,該Activity就被銷(xiāo)毀了萨咳,不會(huì)保留在任務(wù)棧中。如A-B,B中以這種模式啟動(dòng)C迂卢,C再啟動(dòng)D某弦,則任務(wù)棧只有ABD桐汤。
  • Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    ??使用該標(biāo)識(shí)位啟動(dòng)的Activity不添加到最近應(yīng)用列表,也即我們從最近應(yīng)用里面查看不到我們啟動(dòng)的這個(gè)activity靶壮。與屬性android:excludeFromRecents="true"效果相同怔毛。
  • Intent.FLAG_ACTIVITY_NEW_TASK
    該標(biāo)志位表示使用一個(gè)新的Task來(lái)啟動(dòng)一個(gè)Activity,相當(dāng)于在清單文件中給Activity指定“singleTask”啟動(dòng)模式腾降。通常我們?cè)赟ervice啟動(dòng)Activity時(shí)拣度,由于Service中并沒(méi)有Activity任務(wù)棧,所以必須使用該Flag來(lái)創(chuàng)建一個(gè)新的Task螃壤。

使用也非常簡(jiǎn)單:

public static void startActivity(Context context) {
    Intent intent = new Intent(context, HomeActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(new Intent(context, HomeActivity.class));
}

android:taskAffinity

我們重點(diǎn)來(lái)看看taskAffinity這個(gè)標(biāo)簽

android:taskAffinity 官網(wǎng)解釋
與 Activity 有著親和關(guān)系的任務(wù)抗果。從概念上講,具有相同親和關(guān)系的 Activity 歸屬同一任務(wù)(從用戶的角度來(lái)看奸晴,則是歸屬同一“應(yīng)用”)冤馏。 任務(wù)的親和關(guān)系由其根 Activity 的親和關(guān)系確定。
親和關(guān)系確定兩件事 - Activity 更改到的父項(xiàng)任務(wù)(請(qǐng)參閱 allowTaskReparenting 屬性)和通過(guò) FLAG_ACTIVITY_NEW_TASK 標(biāo)志啟動(dòng) Activity 時(shí)將用來(lái)容納它的任務(wù)寄啼。

默認(rèn)情況下逮光,應(yīng)用中的所有 Activity 都具有相同的親和關(guān)系。您可以設(shè)置該屬性來(lái)以不同方式組合它們墩划,甚至可以將在不同應(yīng)用中定義的 Activity 置于同一任務(wù)內(nèi)涕刚。 要指定 Activity 與任何任務(wù)均無(wú)親和關(guān)系,請(qǐng)將其設(shè)置為空字符串乙帮。

如果未設(shè)置該屬性杜漠,則 Activity 繼承為應(yīng)用設(shè)置的親和關(guān)系(請(qǐng)參閱 <application> 元素的 taskAffinity 屬性)。 應(yīng)用默認(rèn)親和關(guān)系的名稱(chēng)是 <manifest> 元素設(shè)置的軟件包名稱(chēng)察净。

我們來(lái)總結(jié)一下上邊文字包含的信息:

  • TASK的taskAffinity是有它的根Activity的taskAffinity決定的驾茴;
  • Activity的taskAffinity默認(rèn)值為所在應(yīng)用程序的包名;
  • taskAffinity影響Activity的任務(wù)(TASK)從屬塞绿;

我們先來(lái)看看截取的一段堆棧信息:

Running activities (most recent first):
      TaskRecord{f51ba40 #6608 A=com.tzx.launchmodel U=0 StackId=1 sz=2}
        Run #3: ActivityRecord{6158b8a u0 com.tzx.launchmodel/.BActivity t6608}
      TaskRecord{3e0d8d2 #6609 A=com.tzx.single U=0 StackId=1 sz=1}
        Run #2: ActivityRecord{d387da3 u0 com.tzx.launchmodel/.CActivity t6609}
      TaskRecord{f51ba40 #6608 A=com.tzx.launchmodel U=0 StackId=1 sz=2}
        Run #1: ActivityRecord{a0bfd79 u0 com.tzx.launchmodel/.AActivity t6608}

該堆棧信息對(duì)應(yīng)的AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tzx.launchmodel" >
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme" >
        <activity android:name=".AActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".BActivity"/>
        <activity android:name=".CActivity"
                  android:taskAffinity="com.tzx.single"
            android:launchMode="singleInstance"/>
    </application>
</manifest>

其中TaskRecord中的A的值就是taskAffinity沟涨。

  • taskAffinity一班與singleTask、singleInstance和allowTaskReparenting標(biāo)簽搭配使用异吻。

這句話又怎么理解呢裹赴?
在解釋這句時(shí)我先想和大家先聊聊Android手機(jī)在使用過(guò)程中為了手機(jī)軟件運(yùn)行的更加流暢,我們一般都會(huì)清理后臺(tái)任務(wù)诀浪。這個(gè)任務(wù)列表是我們最能直觀的看到任務(wù)的存在痕跡棋返。在這里我們會(huì)看到很多情況:一個(gè)應(yīng)用程序的所有Activity一個(gè)任務(wù),多個(gè)應(yīng)用程序的不同Activity一個(gè)任務(wù)雷猪,一個(gè)應(yīng)用程序不同Activity在不同任務(wù)中睛竣。此時(shí)是不是感覺(jué)很懵逼,沒(méi)關(guān)系接下來(lái)我會(huì)講述為什么會(huì)這樣:


taskAffinity.jpg
  • 一個(gè)應(yīng)用程序的所有Activity一個(gè)任務(wù):一班情況下都這樣(不設(shè)置taskAffinity)求摇。
  • 多個(gè)應(yīng)用程序的不同Activity一個(gè)任務(wù):一個(gè)應(yīng)用程序啟動(dòng)另外一個(gè)應(yīng)用程序的Activity并且這里只能是standard或者singleTop模式射沟。因?yàn)槲覀兊贸龅牡谌齻€(gè)結(jié)論taskAffinity只會(huì)對(duì)singleTask殊者、singleInstance有影響,所以在啟動(dòng)standard或者singleTop模式的Activity時(shí)不會(huì)對(duì)比taskAffinity验夯,會(huì)直接在啟動(dòng)它的TASK中啟動(dòng)猖吴。而啟動(dòng)singleTask、singleInstance模式的Activity只能在對(duì)應(yīng)的taskAffinity的TASK中挥转。
  • 一個(gè)應(yīng)用程序不同Activity在不同任務(wù)中:當(dāng)在應(yīng)用程序中我們啟動(dòng)singleTask模式的Activity時(shí)會(huì)尋找與該Activity的taskAffinity相同的TASK當(dāng)中啟動(dòng)海蔽,如果沒(méi)有則會(huì)新建一個(gè)TASK并且這個(gè)TASK在任務(wù)列表里展示。這時(shí)可能比較細(xì)心的同學(xué)會(huì)問(wèn)singleInstance模式的Activity呢绑谣?它每次都會(huì)啟動(dòng)一個(gè)TASK党窜,那么任務(wù)列表里面會(huì)展示這個(gè)TASK么?如果任務(wù)列表中不存在TASK與該singleInstance模式的Activity的taskAffinity
    相同借宵,那么該TASK出現(xiàn)中在任務(wù)列表幌衣。如果有那么不出現(xiàn)在任務(wù)列表。

android:allowTaskReparenting

android:allowTaskReparenting這個(gè)標(biāo)簽我們單獨(dú)抽出來(lái)講一下壤玫,為什么呢泼掠?因?yàn)槲腋杏X(jué)android:allowTaskReparenting和taskAffinity沒(méi)啥關(guān)系,至與launchMode有關(guān)?严浮!挡逼!

android:allowTaskReparenting 官網(wǎng)解釋
當(dāng)啟動(dòng) Activity 的任務(wù)接下來(lái)轉(zhuǎn)至前臺(tái)時(shí)括改,Activity 是否能從該任務(wù)轉(zhuǎn)移至與其有親和關(guān)系的任務(wù) —“true”表示它可以轉(zhuǎn)移,“false”表示它仍須留在啟動(dòng)它的任務(wù)處家坎。
如果未設(shè)置該屬性嘱能,則對(duì) Activity 應(yīng)用由 <application> 元素的相應(yīng) allowTaskReparenting 屬性設(shè)置的值。 默認(rèn)值為“false”虱疏。

正常情況下惹骂,當(dāng) Activity 啟動(dòng)時(shí),會(huì)與啟動(dòng)它的任務(wù)關(guān)聯(lián)做瞪,并在其整個(gè)生命周期中一直留在該任務(wù)處对粪。您可以利用該屬性強(qiáng)制 Activity 在其當(dāng)前任務(wù)不再顯示時(shí)將其父項(xiàng)更改為與其有親和關(guān)系的任務(wù)。該屬性通常用于使應(yīng)用的 Activity 轉(zhuǎn)移至與該應(yīng)用關(guān)聯(lián)的主任務(wù)装蓬。

例如著拭,如果電子郵件包含網(wǎng)頁(yè)鏈接,則點(diǎn)擊鏈接會(huì)調(diào)出可顯示網(wǎng)頁(yè)的 Activity牍帚。 該 Activity 由瀏覽器應(yīng)用定義儡遮,但作為電子郵件任務(wù)的一部分啟動(dòng)。 如果將其父項(xiàng)更改為瀏覽器任務(wù)暗赶,它會(huì)在瀏覽器下一次轉(zhuǎn)至前臺(tái)時(shí)顯示鄙币,當(dāng)電子郵件任務(wù)再次轉(zhuǎn)至前臺(tái)時(shí)則會(huì)消失肃叶。

Activity 的親和關(guān)系由 taskAffinity 屬性定義。 任務(wù)的親和關(guān)系通過(guò)讀取其根 Activity 的親和關(guān)系來(lái)確定十嘿。因此因惭,按照定義,根 Activity 始終位于具有相同親和關(guān)系的任務(wù)之中详幽。 由于具有“singleTask”或“singleInstance”啟動(dòng)模式的 Activity 只能位于任務(wù)的根筛欢,因此更改父項(xiàng)僅限于“standard”和“singleTop”模式。 (另請(qǐng)參閱 launchMode 屬性唇聘。)

上面文字?jǐn)⑹隹偨Y(jié)為一句話:android:allowTaskReparenting可以讓Activity在TASK中轉(zhuǎn)移版姑,但該Activity時(shí)能是“standard”和“singleTop”模式。
至于為什么在講taskAffinity的時(shí)候已經(jīng)介紹清楚了迟郎。實(shí)用場(chǎng)景官網(wǎng)的描述中也有剥险,大家可以參考使用。

文章到這里就全部講述完啦宪肖,若有其他需要交流的可以留言哦~表制!~!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末控乾,一起剝皮案震驚了整個(gè)濱河市么介,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜕衡,老刑警劉巖壤短,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異慨仿,居然都是意外死亡久脯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)镰吆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帘撰,“玉大人,你說(shuō)我怎么就攤上這事万皿〈菡遥” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵牢硅,是天一觀的道長(zhǎng)慰于。 經(jīng)常有香客問(wèn)我,道長(zhǎng)唤衫,這世上最難降的妖魔是什么婆赠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上休里,老公的妹妹穿的比我還像新娘蛆挫。我一直安慰自己,他們只是感情好妙黍,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布悴侵。 她就那樣靜靜地躺著,像睡著了一般拭嫁。 火紅的嫁衣襯著肌膚如雪可免。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天做粤,我揣著相機(jī)與錄音浇借,去河邊找鬼。 笑死怕品,一個(gè)胖子當(dāng)著我的面吹牛妇垢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肉康,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼闯估,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了吼和?” 一聲冷哼從身側(cè)響起涨薪,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炫乓,沒(méi)想到半個(gè)月后尤辱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厢岂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阳距。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塔粒。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖筐摘,靈堂內(nèi)的尸體忽然破棺而出卒茬,到底是詐尸還是另有隱情,我是刑警寧澤咖熟,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布圃酵,位于F島的核電站,受9級(jí)特大地震影響馍管,放射性物質(zhì)發(fā)生泄漏郭赐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一确沸、第九天 我趴在偏房一處隱蔽的房頂上張望捌锭。 院中可真熱鬧俘陷,春花似錦、人聲如沸观谦。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)豁状。三九已至捉偏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泻红,已是汗流浹背夭禽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留承桥,地道東北人驻粟。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像凶异,于是被迫代替她去往敵國(guó)和親蜀撑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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