Activity
一穆刻、四種形態(tài)
運(yùn)行狀態(tài): 當(dāng) Activity 處于棧的頂層,可見(jiàn)逢勾,并可與用戶進(jìn)行交互 onResume()--> onPause()
暫停狀態(tài): 當(dāng) Activity 被非全屏的或者透明的 Activity 遮擋后扰柠,原來(lái)的 Activity 處于暫停狀態(tài) onPause() 被調(diào)用 粉铐,系統(tǒng)內(nèi)存極低時(shí)會(huì)被回收
停止?fàn)顟B(tài): 當(dāng) Activity 被置于后臺(tái)(例如被其它Activity完全遮擋,或者用戶按下 HOME 鍵回到桌面) onStop() 被調(diào)用卤档,系統(tǒng)內(nèi)存極低時(shí)會(huì)被回收
終止?fàn)顟B(tài): 當(dāng) Activity 從未被創(chuàng)建過(guò)或者 Activity 被銷毀(調(diào)用了 Activity 的 finish() 方法或者用戶按下 BACK 鍵蝙泼,表現(xiàn)為 onDestory() 被調(diào)用,但不一定釋放了內(nèi)存)
二劝枣、生命周期
正常聲明周期
onCreate() 表示 Activity 正在被創(chuàng)建汤踏,執(zhí)行加載布局資源织鲸、初始化數(shù)據(jù)等
onRestart() 當(dāng) Activity 從不可見(jiàn)重新變見(jiàn)變?yōu)榭梢?jiàn)時(shí)調(diào)用
onStart() 當(dāng) Activity 正在被啟動(dòng),Activity 已經(jīng)可見(jiàn)溪胶,但是還沒(méi)用開(kāi)始活動(dòng)搂擦,還無(wú)法和用戶進(jìn)行交互,Activity 的布局界面還不可見(jiàn)
onResume() 當(dāng) Activity 可見(jiàn)哗脖,并且已經(jīng)開(kāi)始活動(dòng)瀑踢,可與用戶進(jìn)行交互,并且在這個(gè)方法中將布局顯示到屏幕上
onPause() 當(dāng) Activity 失去焦點(diǎn)才避,不可與用戶交互橱夭,暫停,可以做一些資源回收桑逝,停止動(dòng)畫(huà)操作棘劣,不能耗時(shí)
onStop() 當(dāng) Activity 完全進(jìn)入后臺(tái),可以做一些稍微重量級(jí)的回收工作楞遏,不能耗時(shí)
onDestory() 表示 Activity 即將被銷毀呈础,可以做一些回收工作和最終的資源釋放
生命周期的注意問(wèn)題
當(dāng)Activity被激活時(shí): onCreate() -> onStart() -> onResume()
當(dāng) Activity 被銷毀時(shí):onPause() -> onStop() -> onDestory()
當(dāng) Activity 從不可見(jiàn)重新變見(jiàn)變?yōu)榭梢?jiàn)時(shí),會(huì)經(jīng)歷:onStop() -> onRestart() -> onStart() -> onResume()
當(dāng)新的 Activity 被激活時(shí):原來(lái)的 Activity 先 onPause()橱健,當(dāng)新的 Activity 已經(jīng)完全激活(顯示在前臺(tái))時(shí),原來(lái)的 Activity 會(huì) onStop()
onPause() --> onCreate() --> onStart() --> onResume() --> onStop()當(dāng) A_Activity 被 B_Activity 不完全遮擋而钞,B_Activity 為透明或非全屏,B_Activity 被銷毀時(shí):A_Activity 被重新顯示,會(huì)經(jīng)歷:onPause() -> onResume()
非透明 Activity 啟動(dòng)透明或非全屏 Activity 拘荡,第一個(gè) Activity 不會(huì)執(zhí)行 onStop 臼节,因?yàn)橐恢笨梢?jiàn)
onPause() 方法是系統(tǒng)能銷毀當(dāng)前 Activity 之前調(diào)用的最后一個(gè)方法,所以一些數(shù)據(jù)的保存應(yīng)該放在onPause() 方法中珊皿,但是 onPause() 方法中不能有太多操作网缝,因?yàn)閛nPause() 中任何一個(gè)阻塞的過(guò)程都會(huì)影響向下一個(gè)Activity 轉(zhuǎn)換
Activity 的 onDestory 調(diào)用之后,其中如果有子線程或異步任務(wù)在運(yùn)行蟋定,Thread 和 AsyncTask 并不會(huì)停止粉臊,會(huì)引起 Activity 內(nèi)存泄漏,必須在 onDestory 方法中處理這些線程和 AsyncTask
在 AsyncTask 或者 handler 的返回方法中驶兜,必須對(duì)需要處理的 UI 使用弱引用扼仲,這樣不但可以保證 Activity 中的 UI 控件被正常回收抄淑,并且在處理 UI 控件時(shí)做判空處理屠凶,還能保證在 UI 不存在時(shí)不會(huì)拋出異常
調(diào)用 finish 方法時(shí)的聲明周期 onPause --> onStop --> onDestory
非正常生命周期
第一種非正常生命周期發(fā)生在當(dāng)資源相關(guān)的系統(tǒng)配置發(fā)生改變時(shí),例如橫豎屏切換時(shí)加載的資源會(huì)發(fā)生不同肆资,導(dǎo)致 Activity 被殺死并重建
第二種非正常生命周期發(fā)生情況是在系統(tǒng)內(nèi)存不足時(shí)導(dǎo)致低優(yōu)先級(jí)的 Activity 被殺死矗愧,并在重啟 Activity 時(shí)重建
非正常生命周期中 onSaveInstanceState() 方法中保存狀態(tài)數(shù)據(jù),onCreate() 和 onRestoreInstanceState() 方法中都可以獲取保存的數(shù)據(jù)并恢復(fù)狀態(tài)
非正常生命周期注意問(wèn)題
只有Activity 異常退出以及重建時(shí)以上兩個(gè)方法才會(huì)被調(diào)用
系統(tǒng)銷毀Activity時(shí)會(huì)調(diào)用保存數(shù)據(jù)的方法 onSaveInstanceState()
onRestoreInstanceState() 方法調(diào)用在 onStart() 之后 onResume() 之前
onStart() --> onRestoreInstanceState() --> onResume()
onSaveInstanceState 調(diào)用在 onStop 之前郑原,與onPause 沒(méi)有前后關(guān)系
系統(tǒng)在 onSaveInstanceState 方法中會(huì)調(diào)用有 id 的控件的對(duì)應(yīng)方法保存狀態(tài)唉韭,如果控件沒(méi)有 id 則不會(huì)其保存
配置 configChanges 屬性后夜涕,Activity 在相應(yīng)的資源配置變化時(shí)不會(huì)調(diào)用上述兩個(gè)方法,會(huì)調(diào)用属愤,onConfigurationChanged 方法
Activity 處于前臺(tái)或者可見(jiàn)時(shí)如果系統(tǒng)資源不足女器,也會(huì)在回收 Activity 之前調(diào)用 onSaveInstanceState 方法保存數(shù)據(jù)
onCreate 中使用保存的數(shù)據(jù),需要對(duì) Bundle 做判空驗(yàn)證春塌,onRestoreInstanceState 方法如果被回調(diào)晓避,則 Bundle 一定不為空,建議在 onRestoreInstanceState 方法中使用保存的數(shù)據(jù)
三只壳、啟動(dòng)模式
standard 標(biāo)準(zhǔn)模式
被本應(yīng)用或非本應(yīng)用非 SingleInstance 的 Activity 啟動(dòng)時(shí)俏拱,每次都會(huì)在啟動(dòng)他們的那 Activity 所在的棧中創(chuàng)建一個(gè)新的 Activity,多次創(chuàng)建多次入棧
被本應(yīng)用 singleInstance 的 Activity 啟動(dòng)時(shí)吼句,如果存在以包名為名的棧锅必,則將目標(biāo) Activity 入棧,如果不存在則創(chuàng)建以包名為棧名的棧惕艳,然后入棧
被非本應(yīng)用 singleInstance 的 Activity 啟動(dòng)時(shí)搞隐,如果被啟動(dòng)的 Activity 所屬應(yīng)用未啟動(dòng);將新創(chuàng)建的 Activity 放入棧名為包名新的棧中远搪,并且只會(huì)啟動(dòng)一次劣纲,之后重復(fù)啟動(dòng)都不再重復(fù)創(chuàng)建新的 Activity,并且不執(zhí)行 newIntent 方法
被非本應(yīng)用 singleInstance 的 Activity 啟動(dòng)時(shí)谁鳍,如果被啟動(dòng)的 Activity 所屬應(yīng)用已啟動(dòng)并且該應(yīng)用當(dāng)前棧頂 Activity 為 singleInstance癞季,并且不存在棧名為包名的棧,則會(huì)創(chuàng)建棧名為包名的棧倘潜,然后將新啟動(dòng) Activity 入該棧绷柒,之后重復(fù)啟動(dòng)都不重復(fù)創(chuàng)建新的 Activity,并且不執(zhí)行 newIntent 方法
被非本應(yīng)用 singleInstance 的 Activity 啟動(dòng)時(shí)涮因,如果被啟動(dòng)的 Activity 所屬應(yīng)用已啟動(dòng)并且該應(yīng)用當(dāng)前棧頂 Activity 為 singleInstance废睦,且存在棧名為包名的棧,會(huì)直接將新啟動(dòng) Activity 入該棧养泡,多次啟動(dòng)嗜湃,多次創(chuàng)建并入該棧。
被非本應(yīng)用 singleInstance 的 Activity 啟動(dòng)時(shí)瓤荔,如果被啟動(dòng)的 Activity 所屬應(yīng)用已啟動(dòng)并且該應(yīng)用當(dāng)前棧頂 Activity 為非 singleInstance净蚤,不論當(dāng)前棧頂 Activity 所在棧棧名是否為包名也不論是否有棧名為包名的棧,都會(huì)直接將新啟動(dòng) Activity 入該棧输硝,多次啟動(dòng),多次創(chuàng)建并入該棧程梦。
singleTop 棧頂復(fù)用模式
singleTop 啟動(dòng)時(shí)需要入的棧同 standard
啟動(dòng)時(shí)点把,如果要加入的棧棧頂為需要啟動(dòng)的 Activity橘荠,此時(shí)不會(huì)重復(fù)啟動(dòng),且會(huì)回調(diào) onNewIntent 方法
啟動(dòng)時(shí)郎逃,如果要加入的棧棧頂不是需要啟動(dòng)的 Activity哥童,此時(shí)會(huì)重復(fù)啟動(dòng),且入棧
singleTask 棧內(nèi)復(fù)用模式
singleTask 啟動(dòng)時(shí)需要入的棸玻可以在注冊(cè)時(shí)聲明 TaskAffinity 屬性贮懈,如果沒(méi)有聲明該屬性,則需要入的棧同 standard 优训,不會(huì)創(chuàng)建新的任務(wù)和任務(wù)棧
singleTask 注冊(cè)時(shí)如果聲明 TaskAffinity 屬性朵你,如果啟動(dòng)時(shí)該棧存在則直接入棧,不論要啟動(dòng)該 Activity 的應(yīng)用是否是同一應(yīng)用揣非,并且模式為棧內(nèi)復(fù)用抡医,如果該棧不存在則創(chuàng)建新任務(wù)以及棧名為 TaskAffinity 參數(shù)的棧,并入棧早敬,再啟動(dòng)是不會(huì)創(chuàng)建忌傻,onNewIntent 方法會(huì)被回調(diào)
taskAffinity 值為一個(gè)字符串,其中必須包含包名分隔符 .
系統(tǒng)創(chuàng)建新任務(wù)并實(shí)例化位于新任務(wù)底部的 Activity搞监。但是水孩,如果該 Activity 的一個(gè)實(shí)例已存在于一個(gè)單獨(dú)的任務(wù)中,則系統(tǒng)會(huì)通過(guò)調(diào)用現(xiàn)有實(shí)例的 onNewIntent() 方法向其傳送 Intent琐驴,而不是創(chuàng)建新實(shí)例俘种。一次只能存在 Activity 的一個(gè)實(shí)例。
注:盡管 Activity 在新任務(wù)中啟動(dòng)棍矛,但是用戶按“返回”按鈕仍會(huì)返回到前一個(gè) Activity安疗,不論這個(gè)前 Activity 是不是本應(yīng)用的,可以是桌面够委,其他應(yīng)用的界面等荐类。如果切換其他任務(wù)棧到前臺(tái),則啟動(dòng)一個(gè)在目標(biāo)棧的 Activity 即可將目標(biāo)棧切換到前臺(tái)
這里有一個(gè)問(wèn)題茁帽,就是如果普通棧和 singleTask 棧都存在玉罐,并且這時(shí) singleTask 為后臺(tái)棧,普通棧為前臺(tái)潘拨,普通棧中的 Activity 都出棧之后吊输,singleTask 的棧也不會(huì)顯示到前臺(tái),要想將 singleTask 的棧切換到前臺(tái)铁追,只有再次調(diào)用 singleTask 棧中的 Activity 啟動(dòng)方法季蚂,此時(shí) singleTask 棧中存在的 Activity 不會(huì)重新創(chuàng)建,會(huì)調(diào)用 onNewInent ,不過(guò)也會(huì)同時(shí)切換到前臺(tái)
TaskAffinity 只有和 singleTask 模式結(jié)合使用時(shí)才有意義扭屁,其他啟動(dòng)模式時(shí)沒(méi)意義
singleInstance 單實(shí)例模式
singleInstance 獨(dú)自運(yùn)行在一個(gè)任務(wù)棧中算谈,不同應(yīng)用啟動(dòng)統(tǒng)一個(gè) singleInstance 模式的 Activity 時(shí),該 Activity 只會(huì)創(chuàng)建一次料滥,之后會(huì)調(diào)用 onNewIntent 方法
singleInstance 的 Activity 啟動(dòng)任何 Activity (除非自己) 都會(huì)將目標(biāo) Activity 放入其他的棧中
與 "singleTask" 相同然眼,只是系統(tǒng)不會(huì)將任何其他 Activity 啟動(dòng)到包含實(shí)例的任務(wù)中。該 Activity 始終是其任務(wù)唯一僅有的成員葵腹;由此 Activity 啟動(dòng)的任何 Activity 均在其他的任務(wù)中打開(kāi)高每。
注意:如果 singleInstance 的棧在后臺(tái),顯示到前臺(tái)的方法同 singleTask践宴,以及切換其他棧到前臺(tái)的方式也與 singleTask 的相同
allowTaskReparenting 屬性
在這種情況下鲸匿,Activity 可以從其啟動(dòng)的任務(wù)移動(dòng)到與其具有關(guān)聯(lián)的任務(wù)(如果該任務(wù)出現(xiàn)在前臺(tái))
如果注冊(cè)清單中為 Activity 配置 allTaskReparenting 屬性為 true 之后,默認(rèn)棧名為包名浴井,可以通過(guò) taskAffinity 來(lái)指定想要的棧晒骇,如果從其他任務(wù)棧啟動(dòng)該 Activity 時(shí)該 Activity 指定的棧不存在,此時(shí)不會(huì)創(chuàng)建新棧磺浙,會(huì)將目標(biāo) Activity 放入啟動(dòng)它的 Actiivty 所在棧洪囤,當(dāng)目標(biāo) Activity 指定棧被創(chuàng)建并為前臺(tái)棧時(shí),例如啟動(dòng)該 Activity 所在的應(yīng)用撕氧,此時(shí)已經(jīng)啟動(dòng)的那個(gè) Activity 會(huì)馬上從啟動(dòng)它的應(yīng)用的棧中跳回到本身指定的任務(wù)棧中瘤缩,并獲取棧頂位置,此時(shí)按返回鍵效果為顯示該指定棧中的 Activity
如果從其他應(yīng)用啟動(dòng)該 Activity 時(shí)該 Activity 指定棧已經(jīng)存在伦泥,這時(shí)候從其他棧啟動(dòng)該 Activity 不會(huì)馬上加入指定的棧中剥啤,同樣需要在指定棧切換到前臺(tái)時(shí),例如屏幕首頁(yè)點(diǎn)一下啟動(dòng)該應(yīng)用的圖標(biāo)不脯,這時(shí)候該 Activity 就會(huì)自動(dòng)從啟動(dòng)它的應(yīng)用的棧跳回本身所指定的棧中
啟動(dòng)模式注意問(wèn)題
使用 singleTop/singleTask/singleInstance 時(shí)府怯,如果當(dāng)前界面是這個(gè) Activity,那么再次啟動(dòng)時(shí) onPause --> onNewIntent --> onResume 方法會(huì)依次回調(diào)防楷,onNewIntent 中可以收到新的 Intent 數(shù)據(jù)牺丙,不過(guò)getIntent 得到的還是第一次啟動(dòng)時(shí)的 Intent
使用 singleTask/singleInstance 時(shí),如果當(dāng)前界面不是這個(gè) Activity复局,那么再次啟動(dòng)時(shí) onNewIntent --> onRestart --> onStart --> onResume 方法會(huì)依次回調(diào)冲簿,onNewIntent 中可以收到新的 Intent 數(shù)據(jù),不過(guò)getIntent 得到的還是第一次啟動(dòng)時(shí)的 Intent
當(dāng)注冊(cè)時(shí)指定啟動(dòng)模式且通過(guò) Intent 指定的啟動(dòng)模式同時(shí)存在亿昏,則以 Intent 中指定的為主
注冊(cè)時(shí)指定啟動(dòng)模式不能實(shí)現(xiàn) FLAG_ACTIVITY_CLEAR_TOP 效果
Intent 指定啟動(dòng)模式不能實(shí)現(xiàn) singleInstance 效果
某個(gè)任務(wù)棧中的 Activity 切換到前臺(tái)峦剔,該任務(wù)棧也會(huì)切換到前臺(tái)
如果某應(yīng)用中啟動(dòng)了別的任務(wù),在桌面點(diǎn)擊該應(yīng)用圖標(biāo)時(shí)角钩,該應(yīng)用自己的任務(wù)棧會(huì)回到前臺(tái)
使用 singleTask 以及 singleInstance 時(shí)一定要做好測(cè)試吝沫,因?yàn)椴煌那闆r會(huì)由不同的表現(xiàn)
通過(guò)設(shè)置 Intent 的 Flag 來(lái)設(shè)置啟動(dòng)模式
FLAG_ACTIVITY_SINGLE_TOP 與 singleTop 效果相同
FLAG_ACTIVITY_CLEAR_TOP 如果正在啟動(dòng)的 Activity 已在當(dāng)前任務(wù)中運(yùn)行呻澜,則會(huì)銷毀當(dāng)前任務(wù)頂部的所有 Activity (僅限于其啟動(dòng)模式不是 standart 的情況下),并通過(guò) onNewIntent() 將此 Intent 傳遞給 Activity 已恢復(fù)的實(shí)例(現(xiàn)在位于頂部)野舶,而不是啟動(dòng)該 Activity 的新實(shí)例易迹。
FLAG_ACTIVITY_CLEAR_TOP 通常與 FLAG_ACTIVITY_NEW_TASK 結(jié)合使用宰衙。一起使用時(shí)平道,通過(guò)這些標(biāo)志,可以找到其他任務(wù)中的現(xiàn)有 Activity供炼,并將其放入可從中響應(yīng) Intent 的位置一屋。
注:如果指定 Activity 的啟動(dòng)模式為 "standard",則該 Activity 也會(huì)從堆棧中移除袋哼,并在其位置啟動(dòng)一個(gè)新實(shí)例冀墨,以便處理傳入的 Intent。 這是因?yàn)楫?dāng)啟動(dòng)模式為 "standard" 時(shí)涛贯,將始終為新 Intent 創(chuàng)建新實(shí)例诽嘉。
- FLAG_ACTIVITY_NEW_TASK 在新任務(wù)中啟動(dòng) Activity。如果需要啟動(dòng)的 Activity 存在及需要的任務(wù)也存在弟翘,則該任務(wù)會(huì)轉(zhuǎn)到前臺(tái)并恢復(fù)其最后狀態(tài)虫腋,同時(shí) Activity 會(huì)在 onNewIntent() 中收到新 Intent。
如果已存在目標(biāo) Activity 實(shí)例稀余,并且目標(biāo) Activity 不在棧頂悦冀,此時(shí)如果再調(diào)用啟動(dòng)目標(biāo) Activity 的代碼,Activity 并不會(huì)顯示到前臺(tái)睛琳,因?yàn)?FLAG_ACTIVITY_NEW_TASK 的作用只是在沒(méi)有目標(biāo) Activity 實(shí)例的情況下創(chuàng)建 Activity 實(shí)例盒蟆,并將目標(biāo) Activity 入棧,所以存在 Activity 實(shí)例的情況下在調(diào)用啟動(dòng)方法只是將該任務(wù)會(huì)轉(zhuǎn)到前臺(tái)并恢復(fù)其最后狀態(tài)师骗,此時(shí)該 Activity 不一定在棧頂
FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP 結(jié)合 FLAG_ACTIVITY_SINGLE_TOP 一起使用時(shí)就可以達(dá)到 singleTask 的效果历等,F(xiàn)LAG_ACTIVITY_NEW_TASK 作用為保證目標(biāo) Activity 存在于 taskAffinity 指定棧名相同的棧,并將目標(biāo) Activity 入棧辟癌,F(xiàn)LAG_ACTIVITY_SINGLE_TOP 作用為如果棧中有目標(biāo) Activity寒屯,則將棧中目標(biāo) Activity 之上的 Activity 清除,所以就達(dá)到了 singleTask 的效果愿待。
FLAG_ACTIVITY_NEW_TASK 要產(chǎn)生效果的前提一定是要啟動(dòng)的 Activity 的 taskAffinity 與當(dāng)前 Activity 的是不相同的浩螺,否則就是默認(rèn) standard 的效果
- FLAG_ACTIVITY_CLEAR_TASK 標(biāo)簽,必須與 FLAG_ACTIVITY_NEW_TASK 配合使用仍侥,且必須是 taskAffinity 不同的情況下要出,如果兩個(gè)條件不滿足,則為 standard 模式
如果目標(biāo) Activity 所在棧不存在农渊,則創(chuàng)建新棧并創(chuàng)建目標(biāo) Activity 對(duì)象患蹂,放入該棧
如果目標(biāo) Activity 存在或颊,則將 Activity 及其所在棧中的所有 Activity 全部清空,包括已經(jīng)存在的目標(biāo) Activity 對(duì)象传于,然后重新創(chuàng)建目標(biāo) Activity 囱挑,再放入目標(biāo)棧中
- FLAG_ACTIVITY_NO_HISTORY 使用該標(biāo)簽啟動(dòng)的 Activity 再啟動(dòng)其他 Activity 之后,該 Activity 會(huì)自動(dòng)消失沼溜,即 onDestory 被調(diào)用平挑,不會(huì)保留在 Activity 棧中
...
四、任務(wù)棧
getTaskId() 方法用來(lái)獲取 Activity 所在的任務(wù)棧 ID
Activity 棧中如果沒(méi)有了 Activity 存在則會(huì)銷毀系草,之后再由新 Activity 產(chǎn)生是會(huì)進(jìn)入新的棧中通熄。
在棧中返回時(shí)會(huì)先將當(dāng)前棧中的 Activity 返回,全部返回之后則將跳轉(zhuǎn)到該棧的界面所在的棧切換到前臺(tái)找都,這個(gè)界面可以是屏幕首頁(yè)唇辨,可以是其他應(yīng)用
任務(wù)是指在執(zhí)行特定作業(yè)時(shí)與用戶交互的一系列 Activity。 這些 Activity 按照各自的打開(kāi)順序排列在堆棧(即返回棧)中能耻。
返回棧是任務(wù)的一部分 一個(gè)任務(wù)包含一個(gè)任務(wù)棧赏枚,任務(wù)棧中是一系列 Activity
Android 的多任務(wù)管理,即管理多個(gè)任務(wù)的前臺(tái)后臺(tái)變化
singleTask 如果指定 taskAffinity 或者 singleInstance 都是會(huì)啟動(dòng)新的任務(wù)
首頁(yè)的啟動(dòng)圖標(biāo)作用為 第一:使 Activity 的圖標(biāo)和標(biāo)簽顯示在應(yīng)用啟動(dòng)器中 第二:可以讓用戶在啟動(dòng)之后可以隨時(shí)切換到創(chuàng)建的任務(wù)棧中
通過(guò)為 Activity 提供一個(gè)以 "android.intent.action.MAIN" 為指定操作晓猛、以 "android.intent.category.LAUNCHER" 為指定類別的 Intent 過(guò)濾器饿幅,您可以將 Activity 設(shè)置為任務(wù)的入口點(diǎn)
第二點(diǎn)非常重要,其完成的任務(wù)是鞍帝,如果用戶切換其他任務(wù)棧到前臺(tái)诫睬,則必須為用戶提供方式當(dāng)離開(kāi)任務(wù)棧后還能再次切換到指定棧,首頁(yè)圖標(biāo)則有這個(gè)功能帕涌。
IntentFilter 的匹配規(guī)則
Activity 的 intent-filter 可以有多組摄凡,一個(gè) Intent 只要能匹配任何一組 intent-filter 即可成功啟動(dòng)對(duì)應(yīng) Activity
aciont 匹配規(guī)則:intent-filter 中指定一個(gè)或多個(gè) action,Intent 中的 Action 必須匹配其中任意一個(gè)
intent-filter 中 action 可以多個(gè)蚓曼,Intent 中必須要有唯一的 action亲澡,只要在該 Intent 在 intent-filter 存在即可匹配,action 大小寫(xiě)敏感
intent-filter 中有的 action 最少有一個(gè)纫版,否則無(wú)法被隱式啟動(dòng)
Intent 中 action 必須也只能有一個(gè),否則無(wú)法找到對(duì)應(yīng) Activity
- category 的匹配規(guī)則:Intent 中指定的 category 在 intent-filter 中必須能夠找到
Intent 中有的 intent-filter 中必須有
Intent 中默認(rèn)有 "ndroid.intent.category.DEFAULT" 床绪,即 intent-filter 中至少有 DEFAULT
data 匹配規(guī)則同 Intent ,intent-filter 中定義了 data其弊,Intent 中必須存在最少一個(gè)data可以與 intent-filter 中的任一 data 匹配
data 分為 mimeType 和 URI 兩部分癞己,intent-filter 中 URI 的默認(rèn)支持 content 和 file ,Intent 中沒(méi)有默認(rèn) URI 值梭伐,如果 intent-filter 中不聲明 URI 和 type痹雅,此時(shí) Intent 可以不包含 URI 和 type ,如果 Intent 中定義了 file 或 content 的 URI糊识,intent-filter 中沒(méi)有定義绩社,此時(shí) intent-filter 是支持的
Intent 中調(diào)用 setDataAndType 來(lái)添加 URI 和 mimeType摔蓝,setData 和 setType 方法會(huì)默認(rèn)清除另一對(duì)象的值,所以同時(shí)設(shè)置 data 和 type 時(shí)必須使用 setDataAndType 方法
Intent
判斷是否有接收 Intent 的組件愉耙,并在有多個(gè)響應(yīng)的時(shí)候設(shè)置選擇器名稱
兩種方式判斷是否有接收 Intent 的組件贮尉,第一種是使用 PackageManager 的 resolve... 系列方法判斷,返回值為 null 或者一個(gè)組件朴沿,以及使用 PackageManager 的 queryIntent... 系列方法判斷猜谚,返回值為可以響應(yīng)的組件集合,可以判斷 service悯仙、activity龄毡、BroadcastReceiver
第二種是 Intent 的 resolveActivity 方法判斷,如果有則返回該組件锡垄,如果沒(méi)有返回 null
使用 PackageManager 的方法需要第二個(gè)參數(shù),使用 PackageManager.MATCH_DEFAULT_ONLY 常量來(lái)剔除 intent-filter 中沒(méi)有聲明 默認(rèn) category 的響應(yīng)祭隔,因?yàn)?Intent 默認(rèn)有 category
-
強(qiáng)制使用選擇器來(lái)讓用戶選擇需要啟動(dòng)的 Activity
Intent sendIntent = new Intent(Intent.ACTION_SEND); String title = getResources().getString(R.string.chooser_title); Intent chooser = Intent.createChooser(sendIntent, title); if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
過(guò)濾器中必須指明至少一個(gè)action货岭,Intent 必須有唯一一個(gè) Action,且在過(guò)濾器中必須存在
過(guò)濾器中的 category 必須多于或等于 activity 啟動(dòng)組件使用的 intent 中設(shè)置的
過(guò)濾器中 data 匹配規(guī)則同 action 疾渴,如果 Intent 指明了 URL 而 過(guò)濾器中沒(méi)有 URL千贯,則判斷結(jié)果為假定過(guò)濾器中支持 content 和 file 的 URL
為確保應(yīng)用安全性,啟動(dòng)Service時(shí)搞坝,應(yīng)始終使用顯示 Intent搔谴,且不要為 Service 聲明過(guò)濾器,因?yàn)槭褂秒[式 Intent 啟動(dòng)服務(wù)存在安全隱患桩撮,因?yàn)椴荒艽_定哪些服務(wù)將響應(yīng) Intent敦第,且用戶無(wú)法看到哪些服務(wù)已啟動(dòng)。