Activity的啟動模式

任務(wù)棧

  1. android任務(wù)棧又稱為Task谴返,它是一個棧結(jié)構(gòu)赖晶,具有后進(jìn)先出的特性巾兆,用于存放我們的Activity組件如捅。
  2. 我們每次打開一個新的Activity或者退出當(dāng)前Activity都會在一個稱為任務(wù)棧的結(jié)構(gòu)中添加或者減少一個Activity組件同欠,因此一個任務(wù)棧包含了一個activity的集合, android系統(tǒng)可以通過Task有序地管理每個activity样傍,并決定哪個Activity與用戶進(jìn)行交互:只有在任務(wù)棧棧頂?shù)腶ctivity才可以跟用戶進(jìn)行交互。
  3. 在我們退出應(yīng)用程序時铺遂,必須把所有的任務(wù)棧中所有的activity清除出棧時,任務(wù)棧才會被銷毀衫哥。當(dāng)然任務(wù)棧也可以移動到后臺, 并且保留了每一個activity的狀態(tài). 可以有序的給用戶列出它們的任務(wù), 同時也不會丟失Activity的狀態(tài)信息。
  4. 需要注意的是襟锐,一個App中可能不止一個任務(wù)棧撤逢,某些特殊情況下,單獨一個Actvity可以獨享一個任務(wù)棧粮坞。還有一點就是一個Task中的Actvity可以來自不同的App蚊荣,同一個App的Activity也可能不在一個Task中。

任務(wù)棧信息可以通過 adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'指令來查看 棧信息.

四種啟動模式

  1. standard : 默認(rèn)的啟動模式,每次啟動一個Activity都會重新創(chuàng)建一個新的實例,不管這個實例是否存在.Activity的啟動三回調(diào)(onCreate()->onStart()->onResume())都會執(zhí)行莫杈。 如在一個任務(wù)棧中,連續(xù)調(diào)用3次MainActivity,那么任務(wù)占中就會存在三個MainActivity記錄.
  2. singTop : 棧頂復(fù)用模式. 當(dāng)準(zhǔn)備啟動的Activity已經(jīng)位于任務(wù)棧棧頂時,不會再創(chuàng)建一個新的Activity,此時棧頂Activity的 onNewIntent方法會被回調(diào).當(dāng)準(zhǔn)備啟動的Activity不在任務(wù)棧的棧頂存在時,(無論在棧中存在或者在非棧頂),都會重新創(chuàng)建 Activity.
  3. singleInstance : 單實例模式. 系統(tǒng)為聲明為singleInstance模式的Activity,單獨使用一個任務(wù)棧存放.即一個Activity對應(yīng)一個任務(wù)棧,且一個Activity最多存在一個實例. 后續(xù)請求都不會創(chuàng)建Activity,只會調(diào)用其 onNewIntent回調(diào).
  4. singleTask : 棧內(nèi)復(fù)用模式. 在這種模式下,如果Activity已經(jīng)存在某個任務(wù)棧中,多起啟動該Activity都不會被重建,只會調(diào)用其onNewIntent方法,并將其移動到棧頂位置.

singleTask模式

當(dāng)啟動Activity時,如果Activity已經(jīng)存在于 任務(wù)棧的非棧頂位置, 任務(wù)棧中該Activity之上的 Activity將會被全部移除,只保留該Activity以及其一下的Activity.
即 具有 clearTop的效果.

當(dāng)啟動Activity的任務(wù)棧B在后臺時,此時任務(wù)棧A中的Activity啟動了,任務(wù)棧B中的 singleTask模式的Activity,則任務(wù)B棧的 被啟動Activity會clearTop到棧頂位置,然后整個任務(wù)棧B重返至前臺.

引用 官方示例來說明 :


2018-10-02-22-46-05

前臺棧中的棧頂Activity2 啟動了 位于后臺棧的 ActivityY,此時 后臺棧中的 ActivityY和ActivityX 都會被移動至前臺棧中,回退兩次才能回到 Activity2.

taskAffinity屬性

taskAffinityAndroidManifest中 Activity標(biāo)簽的屬性,表示任務(wù)棧的名稱.該屬性可以為 Activity指定任務(wù)棧.

  1. 當(dāng)Activity的啟動模式為 standard,singletop模式時,taskAffinity屬性將失效, Activity的將被加入到 啟動它的那個Activity所在的棧.一個例外,如果在入口Activity中指定 taskAffinity屬性,則可以生效,因為此時應(yīng)用剛啟動,還沒有指定的任務(wù)棧(默認(rèn)的任務(wù)棧是以包名來命名的).

  2. 當(dāng)Activity的啟動模式為 singleTask,singleInstance模式時,taskAffinity屬性將在Activity被啟動的時候指定任務(wù)棧,如果任務(wù)棧不存在則會創(chuàng)建一個taskAffinity命名的任務(wù)棧存放啟動的Activity.

注意事項

  1. 如果被啟動的Activity是 standard,singletop模式時, Activity將被加入到啟動該Activity的任務(wù)棧中.

  2. 如果被啟動的Activity是 singleTask,singleInstance模式時,如果指定taskAffinity屬性,則Activity被加入到 指定的棧任務(wù)棧中,未指定則被加入 以包名命名的任務(wù)棧. singleInstance模式的Activity,雖然可能被加入到名字相同的棧,但是由于其特殊性,雖然棧名相同但是不屬于同一個棧.

  3. 使用 application來啟動Activity時, application沒有所在的 任務(wù)棧.如果沒有指定 FLAG_ACTIVITY_NEW_TASK,將會有如下報錯.

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

Activity中的 Flags

  1. FLAG_ACTIVITY_NEW_TASK : 為Activity指定 singleTask模式,相當(dāng)于在xml中指定啟動模式一樣,除了application來啟動Activity時,在xml指定singleTask是無效的,一定要在intent中指定該標(biāo)志.
  2. FLAG_ACTIVITY_SINGLE_TOP : 指定singleTop模式.
  3. FLAG_ACTIVITY_CLEAR_TOP : 具有此標(biāo)記的Activity,當(dāng)它啟東市,在同一個任務(wù)棧中的所有位于它上面的Activity都將被移除任務(wù)棧.
  4. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS : 設(shè)置了該標(biāo)志,該Activity所在的任務(wù)棧將不會出現(xiàn)在 多任務(wù)列表(最近使用列表)中.相當(dāng)于設(shè)置了android:excludeFromRecents="true".

IntentFilter匹配規(guī)則

intent的啟動有兩種方式,顯式調(diào)用和隱式調(diào)用.
顯示調(diào)用,我們需要明確的指定被啟動的Activity的組件信息,Activity的class對象.
隱式調(diào)用則不需要明確的知道 被調(diào)用的Activity信息,而是通過IntentFilter來指定action,category,data過濾規(guī)則配合來啟動Activity.

Intent只有同時匹配了 action規(guī)則,category規(guī)則 和 data規(guī)則,才能成功的啟動目標(biāo)Activity.

一個 IntentFilter中可以設(shè)置多個 action,多個category和多個data.

action

intent中必須設(shè)置 action, 且能過匹配 IntentFilter中的任意一個 action就算匹配成功.

category

intent中如果含有 category,那么所有的category都能在IntentFilter中匹配上,intent中也可以不顯式的設(shè)置category.

在調(diào)用 startActivity或者startActivityForResult時,系統(tǒng)會為intent自動添加 android.intent.category.DEFAULT標(biāo)志,所以如果要想隱式的調(diào)用Activity,就必須在 IntentFilter中添加 <category android:name="android.intent.category.DEFAULT" />規(guī)則.

data

<data android:scheme="string"
      android:host="string"
      android:port="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:mimeType="string" />

data由兩部分組成, URI 和 mimeType(媒體類型).

URI結(jié)構(gòu) : <scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>]
mimeType : image/jpeg,video/*等.

如果IntentFilter中設(shè)置了 data屬性.則intent中必須設(shè)置 setData或者setType或者setDataAndType.
setData或者setType方法的屬性會相互覆蓋.各自的方法會將對方屬性設(shè)置為null.

當(dāng)data中指設(shè)置了 mimeType時,可以使用 schemefile或content類型來設(shè)置data.
如果需要同時指定URImimeType,需要使用intent的setDataAndType方法.

隱式調(diào)用,可達(dá)性檢查

隱式intent啟動之前,我們可以先檢查 目標(biāo)Activity的可達(dá)性,避免出現(xiàn) android.content.ActivityNotFoundException: No Activity found to handle Intent的錯誤.

使用 intent的 intent.resolveActivity(packageManager) 和 packageManager的packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)來檢查, 返回 null則表示找不到匹配的Activity.

參考

  1. Android開發(fā)藝術(shù)探索(任玉剛)
  2. 任務(wù)和返回棧(android官方教程)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末互例,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子筝闹,更是在濱河造成了極大的恐慌媳叨,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件关顷,死亡現(xiàn)場離奇詭異糊秆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)议双,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門痘番,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人聋伦,你說我怎么就攤上這事夫偶〗缯觯” “怎么了觉增?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵兵拢,是天一觀的道長。 經(jīng)常有香客問我逾礁,道長说铃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任嘹履,我火速辦了婚禮腻扇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砾嫉。我一直安慰自己幼苛,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布焕刮。 她就那樣靜靜地躺著舶沿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪配并。 梳的紋絲不亂的頭發(fā)上括荡,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音溉旋,去河邊找鬼畸冲。 笑死,一個胖子當(dāng)著我的面吹牛观腊,可吹牛的內(nèi)容都是我干的邑闲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼梧油,長吁一口氣:“原來是場噩夢啊……” “哼监憎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婶溯,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤鲸阔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后迄委,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褐筛,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年叙身,在試婚紗的時候發(fā)現(xiàn)自己被綠了渔扎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡信轿,死狀恐怖晃痴,靈堂內(nèi)的尸體忽然破棺而出残吩,到底是詐尸還是另有隱情,我是刑警寧澤倘核,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布泣侮,位于F島的核電站,受9級特大地震影響紧唱,放射性物質(zhì)發(fā)生泄漏活尊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一漏益、第九天 我趴在偏房一處隱蔽的房頂上張望蛹锰。 院中可真熱鬧,春花似錦绰疤、人聲如沸铜犬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽癣猾。三九已至,卻和暖如春榨了,著一層夾襖步出監(jiān)牢的瞬間煎谍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工龙屉, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留呐粘,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓转捕,卻偏偏與公主長得像作岖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子五芝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

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