Android Intent解析
本文大部分參考自?http://blog.csdn.net/mayingcai1987/article/details/6200909?,對(duì)原文中的講解FLAG_NEW_TASK地方加了一些自己的觀點(diǎn),用紅色標(biāo)記
1. Task是包含一系列Activity的堆棧, 遵循先進(jìn)后出原則.?
2. Task默認(rèn)行為:?
??? (1)?前提: Activity A和Activity B在同一個(gè)應(yīng)用中.?
?????????操作: Activity A啟動(dòng)開僻Task堆棧(堆棧狀態(tài): A), 在Activity A中啟動(dòng)Activity B(堆棧狀態(tài): AB), 按下BACK返回鍵(堆棧狀態(tài): A).?
??? (2) 前提: Activity A和Activity B在同一個(gè)應(yīng)用中, 應(yīng)用名稱為"TaskOne應(yīng)用".
???????? 操作: 在Launcher中單擊"TaskOne應(yīng)用"圖標(biāo), Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
?????????????????在Activity A中啟動(dòng)Activity B(TaskA堆棧狀態(tài): AB), 長按Home鍵, 返回Launcher, 啟動(dòng)其它應(yīng)用(如:電子書),
?????????????????開僻一個(gè)新Task堆棧, 命名: TaskB, 長按Home健, 返回Launcher, 單擊"TaskOne應(yīng)用"圖標(biāo), 此時(shí)TaskA堆棧返回前臺(tái),
?????????????????Activity B為棧頂應(yīng)用, 供用戶使用.?
??? (3) 前提: Activity A在名稱為"TaskOne應(yīng)用"的應(yīng)用中, Activity C在名稱為"TaskTwo應(yīng)用"的應(yīng)用中.
???????? 操作: 在Launcher中單擊"TaskOne應(yīng)用"圖標(biāo), Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
?????????????????在Activity A中啟動(dòng)Activity C(TaskA堆棧狀態(tài): AC),長按Home鍵, 返回Launcher, 啟動(dòng)"TaskTwo應(yīng)用"即Activity C,
?????????????????開僻新的Task堆棧, 命名為TaskB, 按BACK鍵返回Launcher, 單擊"TaskOne應(yīng)用"圖標(biāo), 此時(shí)TaskA堆棧返回前臺(tái),
?????????????????Activity C為棧頂應(yīng)用, 供用戶使用.?
3. Intent FLAG介紹:
??? (1) FLAG_ACTIVITY_NEW_TASK: 設(shè)置此狀態(tài),記住以下原則,首先會(huì)查找是否存在和被啟動(dòng)的Activity具有相同的親和性的任務(wù)棧(即taskAffinity,注意同一個(gè)應(yīng)用程序中的activity的親和性一樣,所以下面的a情況會(huì)在同一個(gè)棧中,前面這句話有點(diǎn)拗口,請(qǐng)多讀幾遍),如果有,剛直接把這個(gè)棧整體移動(dòng)到前臺(tái),并保持棧中的狀態(tài)不變,即棧中的activity順序不變,如果沒有,則新建一個(gè)棧來存放被啟動(dòng)的activity
???????? a. 前提: Activity A和Activity B在同一個(gè)應(yīng)用中.?
???????????? 操作: Activity A啟動(dòng)開僻Task堆棧(堆棧狀態(tài): A), 在Activity A中啟動(dòng)Activity B, 啟動(dòng)Activity B的Intent的Flag設(shè)為
???????????????????? FLAG_ACTIVITY_NEW_TASK, Activity B被壓入Activity A所在堆棧(堆棧狀態(tài): AB).
? ? ? ? ? ? 原因: 默認(rèn)情況下同一個(gè)應(yīng)用中的所有Activity擁有相同的關(guān)系(taskAffinity).
???????? b. 前提: Activity A在名稱為"TaskOne應(yīng)用"的應(yīng)用中, Activity C和Activity D在名稱為"TaskTwo應(yīng)用"的應(yīng)用中.
???????????? 操作1: 在Launcher中單擊"TaskOne應(yīng)用"圖標(biāo), Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
?????????????????????? 在Activity A中啟動(dòng)Activity C, 啟動(dòng)Activity C的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK,
?????????????????????? Android系統(tǒng)會(huì)為Activity C開僻一個(gè)新的Task, 命名為TaskB(TaskB堆棧狀態(tài): C), 長按Home鍵, 選擇TaskA,
?????????????????????? Activity A回到前臺(tái), 再次啟動(dòng)Activity C(兩種情況1.從桌面啟動(dòng);2.從Activity A啟動(dòng),兩種情況一樣), 這時(shí)TaskB回到前臺(tái), Activity C顯示, 供用戶使用, 即:
?????????????????????? 包含F(xiàn)LAG_ACTIVITY_NEW_TASK的Intent啟動(dòng)Activity的Task正在運(yùn)行, 則不會(huì)為該Activity創(chuàng)建新的Task,
?????????????????????? 而是將原有的Task返回到前臺(tái)顯示.
???????????? 操作2: 在Launcher中單擊"TaskOne應(yīng)用"圖標(biāo), Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
???????????????????????在Activity A中啟動(dòng)Activity C,啟動(dòng)Activity C的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK,
???????????????????????Android系統(tǒng)會(huì)為Activity C開僻一個(gè)新的Task, 命名為TaskB(TaskB堆棧狀態(tài): C),??在Activity C中啟動(dòng)
?????????????????????? Activity D(TaskB的狀態(tài): CD) 長按Home鍵, 選擇TaskA, Activity A回到前臺(tái), 再次啟動(dòng)Activity C(從桌面或者ActivityA啟動(dòng),也是一樣的),
?????????????????????? 這時(shí)TaskB回到前臺(tái), Activity D顯示,供用戶使用.說明了在此種情況下設(shè)置FLAG_ACTIVITY_NEW_TASK后,會(huì)先查找是不是有Activity C存在的棧,根據(jù)親和 性(taskAffinity),如果有,剛直接把這個(gè)棧整體移動(dòng)到前臺(tái),并保持棧中的狀態(tài)不變,即棧中的順序不變
????(2) FLAG_ACTIVITY_CLEAR_TOP:
???????? 前提: Activity A, Activity B, Activity C和Activity D在同一個(gè)應(yīng)用中.
???????? 操作: Activity A啟動(dòng)開僻Task堆棧(堆棧狀態(tài): A), 在Activity A中啟動(dòng)Activity B(堆棧狀態(tài): AB), 在Activity B中啟動(dòng)
???????????????? Activity C(堆棧狀態(tài): ABC), 在Activity C中啟動(dòng)Activity D(堆棧狀態(tài): ABCD), 在Activity D中啟動(dòng)Activity B,
?????????????????啟動(dòng)Activity B的Intent的Flag設(shè)置為FLAG_ACTIVITY_CLEAR_TOP, (堆棧狀態(tài): AB).
??? (3) FLAG_ACTIVITY_BROUGHT_TO_FRONT:
???????? 前提: Activity A在名稱為"TaskOne應(yīng)用"的應(yīng)用中, Activity C和Activity D在名稱為"TaskTwo應(yīng)用"的應(yīng)用中.
???????? 操作: 在Launcher中單擊"TaskOne應(yīng)用"圖標(biāo), Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
???????????????? 在Activity A中啟動(dòng)Activity C,啟動(dòng)Activity C的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK,
??????????????? ?Android系統(tǒng)會(huì)為Activity C開僻一個(gè)新的Task, 命名為TaskB(TaskB堆棧狀態(tài): C), 在Activity C中啟動(dòng)
???????????????? Activity D(TaskB的堆棧狀態(tài): CD), 長按Home鍵, 選擇TaskA, Activity A回到前臺(tái), 在Activity A中再次啟動(dòng)Activity C,
??????????????? ?在啟動(dòng)Activity C的Intent中設(shè)置Flag為FLAG_ACTIVITY_BROUGHT_TO_FRONT, TaskB回到前臺(tái),
???????????????? Activity C顯示, (TaskB的堆棧狀態(tài): C).
??? (4) FLAG_ACTIVITY_MULTIPLE_TASK:
???????? 與FLAG_ACTIVITY_NEW_TASK結(jié)合使用, 首先在Intent中設(shè)置FLAG_ACTIVITY_NEW_TASK, 打開Activity,
?????????則啟動(dòng)一個(gè)新Task, 接著在Intent中設(shè)置FLAG_ACTIVITY_MULTIPLE_TASK, 再次打開同一個(gè)Activity,則還會(huì)新啟動(dòng)一個(gè)Task.
??? (5) FLAG_ACTIVITY_SINGLE_TOP:
?????????當(dāng)前Task堆棧中存在ABCD四個(gè)Activity, A是棧頂Activity, D為棧底Activity, 存在打開A的Intent中設(shè)置了
???????? FLAG_ACTIVITY_SINGLE_TOP標(biāo)志, 則會(huì)使用棧頂A, 而不會(huì)從新New A.
??? (6) FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:
一般與FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET結(jié)合使用,如果設(shè)置該屬性,這個(gè)activity將在一個(gè)新的task中啟動(dòng)或者或者被帶到一個(gè)已經(jīng)存在的task的頂部,這時(shí)這個(gè)activity將會(huì)作為這個(gè)task的首個(gè)頁面加載。將會(huì)導(dǎo)致與這個(gè)應(yīng)用具有相同親和力的task處于一個(gè)合適的狀態(tài)(移動(dòng)activity到這個(gè)task或者從中移出),或者簡單的重置這個(gè)task到它的初始狀態(tài)
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:在當(dāng)前的Task堆棧中設(shè)置一個(gè)還原點(diǎn),當(dāng)帶有FLAG_ACTIVITY_RESET_TASK_IF_NEEDED的Intent請(qǐng)求啟動(dòng)這個(gè)堆棧時(shí)(典型的例子是用戶從桌面再次啟動(dòng)這個(gè)應(yīng)用),還原點(diǎn)之上包括這個(gè)應(yīng)用將會(huì)被清除。應(yīng)用場景:在email程序中預(yù)覽圖片時(shí),會(huì)啟動(dòng)圖片觀覽的actvity,當(dāng)用戶離開email處理其他事情,然后下次再次從home進(jìn)入email時(shí),我們呈現(xiàn)給用戶的應(yīng)該是上次email的會(huì)話,而不是圖片觀覽,這樣才不會(huì)給用戶造成困惑。
???????? 例: 存在Activity A, Activity B, Activity C, Activity A啟動(dòng)開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態(tài): A),
????????????? 在Activity A中啟動(dòng)Activity B(TaskA堆棧狀態(tài): AB), 接著Activity B啟動(dòng)Activity C(TaskA堆棧狀態(tài): ABC),
??????????????啟動(dòng)Activity C的Intent中設(shè)置FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET標(biāo)題, 這樣TaskA中有一個(gè)還原點(diǎn),
????????????? 當(dāng)有包含F(xiàn)LAG_ACTIVITY_RESET_TASK_IF_NEEDED的Intent請(qǐng)求TaskA堆棧時(shí)(比如請(qǐng)求Activity A)
????????????? 系統(tǒng)就會(huì)將還原點(diǎn)以上的Activity清除, TaskA堆棧中只剩下了AB.
4. launchMode介紹:
??? (1) standard:?
???????? 如果啟動(dòng)此Activity的Intent中沒有設(shè)置FLAG_ACTIVITY_NEW_TASK標(biāo)志, 則這個(gè)Activity與啟動(dòng)他的Activity在同一個(gè)Task中,
???????? 如果設(shè)置了Activity請(qǐng)參考上面FLAG_ACTIVITY_NEW_TASK的詳細(xì)說明,"launchMode"設(shè)置為"standard"的
???????? Activity可以被實(shí)例化多次, 可以在Task中的任何位置, 對(duì)于一個(gè)新的Intent請(qǐng)求就會(huì)實(shí)例化一次.
?? (2) singleTop:?
???????? 如果啟動(dòng)此Activity的Intent中沒有設(shè)置FLAG_ACTIVITY_NEW_TASK標(biāo)志, 則這個(gè)Activity與啟動(dòng)他的Activity在同一個(gè)Task中,
?????????如果設(shè)置了Activity請(qǐng)參考上面FLAG_ACTIVITY_NEW_TASK的詳細(xì)說明,"launchMode"設(shè)置為"singleTop"的Activity可以被
???????? 實(shí)例化多次,??可以在Task中的任何位置, 對(duì)于一個(gè)新的Intent請(qǐng)求如果在Task棧頂, 則會(huì)用棧頂?shù)腁ctivity響影Intent請(qǐng)求,
???????? 而不會(huì)重新實(shí)例化對(duì)象接收請(qǐng)求, 如果沒有在棧頂, 則會(huì)實(shí)例化一個(gè)新的對(duì)象接收Intent請(qǐng)求.
?? (3) singleTask:?
??????? "launchMode"設(shè)置為"singleTask"的Activity總是在棧底, 只能被實(shí)例化一次, 它允許其它Activity壓入"singleTask"的Activity
???????? 所在的Task棧,如果有新的Intent請(qǐng)求有此標(biāo)志的Activity, 則系統(tǒng)會(huì)清除有此標(biāo)志的Task棧中的全部Activity,并把此Activity顯示出來.
?? (4) singleInstance:?
???????? launchMode"設(shè)置為"singleInstance"的Activity總是在棧底, 只能被實(shí)例化一次, 不允許其它的Activity壓入"singleInstance"
???????? 的Activity所在Task棧,??即整個(gè)Task棧中只能有這么一個(gè)Activity.
5. taskAffinity屬性:?
?? (1) taskAffinity屬性應(yīng)和FLAG_ACTIVITY_NEW_TASK標(biāo)志及allowTaskReparenting屬性結(jié)合使用, 如果只使用taskAffinity屬性,
????????請(qǐng)參考上面Task默認(rèn)的行為.
?? (2) 與FLAG_ACTIVITY_NEW_TASK標(biāo)志結(jié)合:
?????? a. 前題: Activity A和Activity B在同一個(gè)應(yīng)用中, Activity A與Activity B設(shè)置不同的taskAffinity屬性.
?????????? 操作: Activity A啟動(dòng)開僻Task堆棧,命名為TaskA(TaskA堆棧狀態(tài): A), 在Activity A中啟動(dòng)Activity B, 啟動(dòng)Activity B
???????????????????的Intent中設(shè)置FLAG_ACTIVITY_NEW_TASK標(biāo)志,這時(shí)系統(tǒng)會(huì)新開僻一個(gè)Task堆棧,TaskB(TaskB堆棧狀態(tài): B).
?????? b. 前題: Activity A在"TaskOne應(yīng)用"中, Activity C在"TaskTwo應(yīng)用"中, Activity A和ActivityC設(shè)置了相同的taskAffinity屬性.
?????????? 操作: Activity A啟動(dòng)開僻Task堆棧,命名為TaskA(TaskA堆棧狀態(tài): A), 在Activity A中啟動(dòng)Activity C, 啟動(dòng)Activity C的
???????????????????Intent中設(shè)置FLAG_ACTIVITY_NEW_TASK標(biāo)志,這時(shí)Activity C會(huì)壓入與Activity A堆棧相同的TaskA堆棧(TaskA堆棧狀態(tài): AC).
?? (3) 與allowTaskReparenting屬性:
???????? 例: 在"TaskOne應(yīng)用"中有一個(gè)天氣預(yù)報(bào)Activity A, Activity A與"TaskOne應(yīng)用"中的其它Activity有默認(rèn)的關(guān)系
??????????????(taskAffinity屬性都沒有設(shè)置), 并且allowTaskReparenting屬性設(shè)置為true, 現(xiàn)在存在一個(gè)"TaskTwo應(yīng)用
????????????? "啟動(dòng)了"TaskOne應(yīng)用"中的天氣預(yù)報(bào)Activity A,??這時(shí)Activity A與"TaskTwo應(yīng)用"中的Activity在同一個(gè)Task,
??????????????命名這個(gè)Task堆棧為TaskA, 這時(shí)"TaskOne應(yīng)用"啟動(dòng), 并且又打開發(fā)天氣預(yù)報(bào)Activity A, 這時(shí)Activity A會(huì)從TaskA堆棧中轉(zhuǎn)移到
????????????? "TaskOne應(yīng)用"所在的堆棧, 即Activity A可以在多個(gè)堆棧中來回轉(zhuǎn)移.???????
6. alwaysRetainTaskState屬性:
????如果Task堆棧中的Root Activity設(shè)置了此屬性值為true, 不管出現(xiàn)任何情況, 一直會(huì)保留Task棧中Activity的狀態(tài).
7. clearTaskOnLaunch屬性:????
??? 如果Task堆棧中的Root Activity設(shè)置了此屬性值為true, 只要你一離開這個(gè)Task棧, 則系統(tǒng)會(huì)馬上清理除了Root Activity的全部Activity.
8. finishOnTaskLaunch屬性:
??? 如果某Activity設(shè)置了finishOnTaskLaunch屬性, 只要你一離開這個(gè)Task棧, 則系統(tǒng)會(huì)馬上清除這個(gè)Activity,
??? 不管這個(gè)Activity在堆棧的任何位置.
總結(jié)
以上是生活随笔為你收集整理的Android Intent解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 反编译APK文件的三种方法
- 下一篇: Android 下 APK 捆绑器的实现