LaunchMode & Intent Flag?&?TaskAffinity
LaunchMode
launchMode分為四種:?
standard啟動模式為最基本的啟動模式拒迅,默認(rèn)為該種啟動模式蒸甜,特點就是每當(dāng)發(fā)送一個intent請求打開該activity時账蓉,都會創(chuàng)建一個新的activity實例。實際使用情況分為兩種,一種是本應(yīng)用打開经瓷,一種是跨應(yīng)用打開:
本應(yīng)用打開,新創(chuàng)建的activity實例放入本應(yīng)用,即發(fā)送intent的task棧的頂部隘马,這個比較簡單
跨引用打開,這里有一個需要注意的地方是跨應(yīng)用打開的時候會在 Recent app 頁面顯示兩個獨立項妻顶,但是此時它們兩個 Activity 仍然是在一個棧中酸员,非常感謝@夢想編制楠灬 的指正蜒车,跨應(yīng)用打開在 Standard 模式下也是在一個棧中句旱,雖然在 Recent app 頁面是兩個頁面:?
但是問題來了蒂阱,又一次我偶然發(fā)現(xiàn)使用瀏覽器打開手機上的bilibili則是在同一個 Recent App 項中:?
使用命令adb shell dumpsys activity獲取手機的的activity棧的詳細(xì)信息
如上圖所示笋妥,com.htc.sense.browser/.BrowserActivity和tv.danmaku.bili/.ui.video.VideoDetailsActivity在同一個 recent app 頁面中刃永,這是怎么回事了夹厌,最后我發(fā)現(xiàn)有一個intent的flag變量有該作用:FLAG_ACTIVITY_RESET_TASK_IF_NEEDED与学,只要將該flag設(shè)置進intent中就會將跨應(yīng)用的activity打開在同一個 Recent app 中丰泊,感興趣的可以試一下喷户。
singleTop其實和standard幾乎一樣汇恤,和standard算一組庞钢,使用singleTop的Activity也可以創(chuàng)建很多個實例。唯一不同的就是因谎,如果調(diào)用的目標(biāo)Activity已經(jīng)位于調(diào)用者的Task的棧頂基括,則不創(chuàng)建新實例,而是使用當(dāng)前的這個Activity實例财岔,并調(diào)用這個實例的onNewIntent方法风皿。?
這個使用場景比較少,可以使用的例子比如用戶已經(jīng)在當(dāng)前activity使鹅,用戶點擊一條推送消息之后也需要跳轉(zhuǎn)到當(dāng)前activity揪阶,那么為了避免activity的重復(fù)打開,則需要將該activity設(shè)置為singleTop并且復(fù)寫onNewIntent即可患朱。?
如果是外部程序啟動singleTop的Activity鲁僚,表現(xiàn)都和standard一樣。
使用singleTask啟動模式的Activity?在系統(tǒng)中?只會存在一個實例裁厅。如果這個實例已經(jīng)存在冰沙,intent就會通過onNewIntent傳遞到這個Activity,并且將棧中該activity之上的activity清除(銷毀過程會調(diào)用Activity生命周期回調(diào))执虹,如果不存在新的Activity實例將被創(chuàng)建拓挥。?
實際使用情況也分為兩組:
本應(yīng)用啟動,在一個應(yīng)用中啟動設(shè)置為singleTask的activity袋励,如果該activity在task棧中不存在侥啤,則會創(chuàng)建一個新的實例放在棧頂,如果在activity的task棧中已經(jīng)存在了該activity實例茬故,則會將棧中該activity實例之上的其他activity實例清空盖灸,并且會調(diào)用該activity的onNewIntent方法。最常用的使用例子就是首頁磺芭,比如首頁上面已經(jīng)有了很多的activity赁炎,回到首頁就可以使用這種方式,然后復(fù)寫首頁的onNewIntent方法钾腺。使用提示:onNewIntent方法中不能進行fragment的相關(guān)操作http://blog.sina.com.cn/s/blog_5da93c8f0101rgb2.html
跨應(yīng)用啟動徙垫,由于整個系統(tǒng)只能存在activity的一個實例讥裤,所以如果系統(tǒng)中不存在該activity,則會啟動一個新的task去啟動該activity姻报,并且將該activity放入棧底己英。如果系統(tǒng)中存在該activity實例,則會直接啟動該activity吴旋,調(diào)用該activity的onNewIntent的方法剧辐,同時將該activity task棧上面的其他activity清空(銷毀過程會調(diào)用Activity生命周期回調(diào)),此時如果用戶摁下返回鍵邮府,那么將在singleTask activity的task棧中操作荧关,即返回該棧中singleTask activity的上一個activity直到該棧中無activity時才會返回到最開始啟動singleTask activity的activity中。還有一種情況是singleTask Activity所在的應(yīng)用進程存在褂傀,但是singleTask Activity實例不存在忍啤,那么從別的應(yīng)用啟動這個Activity,新的Activity實例會被創(chuàng)建仙辟,并放入到所屬進程所在的Task中同波,并位于棧頂位置。
注意如果使用了singleTask叠国,FLAG_ACTIVITY_RESET_TASK_IF_NEEDED這個flag將會失效未檩。?
需要特別注意的是:?
1.在4.x和之前的系統(tǒng)下,A1(startActivityForResult)->A2(singleTask, startActivityForResult)->A3->A4粟焊,當(dāng)A1打開A2之后會立即回調(diào)onActivityResult()函數(shù)冤狡,A2打開A3仍然可以正常回調(diào)onActivityResult()项棠;但是從5.0開始悲雳,A1打開A2的時候 onActivityResult() 函數(shù)也能正常的回調(diào),不會立即回調(diào)香追。?
2.在4.x和之前的系統(tǒng)下合瓢,A1(startActivityForResult)->A2(singleTask, startActivityForResult)->A3,生命周期的流程是
(注:onCreate和onDestroy這兩個生命周期沒有變化透典,所以沒有加進去晴楔,還有一個是A1.onStop生命周期在A2.onResume之后這個是不一定的,視情況而定)峭咒,上面的變化必須要是startActivityForResult()+5.0之前的系統(tǒng)才會出現(xiàn)税弃,可以推測是由于onActivityResult()函數(shù)引起的這個問題。
和singleTask類似讹语,在系統(tǒng)中?只會存在一個實例钙皮,唯一的區(qū)別就是系統(tǒng)不會在singleInstance activity的task棧中啟動任何其他的activity蜂科,singleInstance activity棧中僅僅只能有該activity的實例顽决,其他任何從這個activity啟動的activity都會在其他的棧中被打開短条。?
雖然使用adb shell dumpsys activity可以看到singleInstance activity在一個獨立的task中,但是在任務(wù)管理器中才菠,還是顯示的一個?
需要特別注意的是:?
1.A1->A2(SingleInstance)茸时,摁下 Home 鍵之后,點擊應(yīng)用圖標(biāo)再次進入應(yīng)用赋访,返回的是 A1 頁面可都,這是因為 A2 在另一個單獨的 Activity task 棧中,點擊圖標(biāo)返回的是主 Activity 棧蚓耽,所以此時顯示的 A1 頁面渠牲,而不是 A2 頁面。?
2.注意singleInstance的返回鍵的處理和上面3個 mode 有區(qū)別步悠,如果是使用正常的 startActivity 進行的啟動签杈,啟動順序A1->A2->A3(singleInstance)->A4,在A4頁面摁下back鍵鼎兽,返回的是A2答姥,再返回A1,接著再次摁下back鍵谚咬,返回的才是A3鹦付;如果是使用 startActivityForResult 啟動的,在4.x和之前的系統(tǒng)下择卦,表現(xiàn)和之前是一樣的敲长,但是在5.0開始,A1->A2-A3(singleInstance + startActivityForResult)->A4秉继,在A4摁下返回鍵潘明,返回的是A3->A2->A1,這個需要著重說明一下秕噪。?
3.另一個比較重要的是钳降,在4.x和之前的系統(tǒng)下,A1(startActivityForResult)->A2(singleInstance, startActivityForResult)->A3->A4腌巾,當(dāng)A1打開A2之后會立即回調(diào)onActivityResult()函數(shù)遂填,A2打開A3也會立即回調(diào)onActivityResult()函數(shù);但是從5.0開始澈蝙,A1打開A2和A2打開A3的兩種情況下 onActivityResult() 函數(shù)都能正常的回調(diào)吓坚,不會立即回調(diào)。?
4.還有一個比較重要的是灯荧,在4.x和之前的系統(tǒng)下礁击,A1(startActivityForResult)->A2(singleInstance, startActivityForResult)->A3,生命周期的流程是
和singleTask一樣,也是必須要是startActivityForResult()+5.0之前的系統(tǒng)才會出現(xiàn)哆窿,區(qū)別就只是A2打開A3的情況不同链烈。
Intent的flag有很多,介紹一下吧
FLAG_ACTIVITY_BROUGHT_TO_FRONT?
比方說我現(xiàn)在有A挚躯,在A中啟動B强衡,在A中Intent中加上這個標(biāo)記。此時B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT 這個啟動的码荔,在B中再啟動C漩勤,D(正常啟動C,D)缩搅,如果這個時候在D中再啟動B越败,這個時候最后的棧的情況是 A,C,D,B.。?
如果在調(diào)用startActivity時傳遞這個標(biāo)記硼瓣,該task棧中的其他activity會先被清空眉尸,然后該activity在該task中啟動,也就是說巨双,這個新啟動的activity變?yōu)榱诉@個空task的根activity噪猾。所有老的activity都結(jié)束掉。該標(biāo)志必須和FLAG_ACTIVITY_NEW_TASK一起使用筑累。?
如果該activity已經(jīng)在task中存在袱蜡,并且設(shè)置了該task,系統(tǒng)不會啟動新的 Activity 實例慢宗,會將task棧里該Activity之上的所有Activity一律結(jié)束掉坪蚁,然后將Intent發(fā)給這個已存在的Activity。Activity收到 Intent之后镜沽,或者在onNewIntent()里做下一步的處理敏晤,或者自行結(jié)束然后重新創(chuàng)建自己。如果 Activity 在 AndroidMainifest.xml 里將啟動模式設(shè)置成默認(rèn)standard模式缅茉,并且 Intent 里也沒有設(shè)置 FLAG_ACTIVITY_SINGLE_TOP嘴脾,那么他將會結(jié)束并且重啟;否則則會傳遞到onNewIntent方法蔬墩,F(xiàn)LAG_ACTIVITY_CLEAR_TOP 還可以和 FLAG_ACTIVITY_NEW_TASK 配合使用译打,用來啟動一個task棧的根activity,他將會把該棧清空為根狀態(tài)拇颅,比如從notification manager啟動activity奏司。?
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET?
已經(jīng)廢棄,請使用FLAG_ACTIVITY_NEW_DOCUMENT?
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS?
設(shè)置完之后樟插,新的activity將不會添加到當(dāng)前activity列表中韵洋,當(dāng)某些情況下我們不希望用戶通過歷史列表回到我們的Activity的時候這個標(biāo)記比較有用竿刁。他等同于在XML中指定Activity的屬性android:excludeFromRecents=”true”。?
如果設(shè)置搪缨,并且這個Intent用于從一個存在的Activity啟動一個新的Activity食拜,那么,這個作為答復(fù)目標(biāo)的Activity將會傳到這個新的Activity中勉吻。這種方式下,新的Activity可以調(diào)用setResult(int)旅赢,并且這個結(jié)果值將發(fā)送給那個作為答復(fù)目標(biāo)的Activity齿桃。?
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY?
一般由系統(tǒng)調(diào)用,比如長摁home鍵從歷史記錄中啟動煮盼。?
這個標(biāo)識用來創(chuàng)建一個新的task棧短纵,并且在里面啟動新的activity(所有情況,不管系統(tǒng)中存在不存在該activity實例)僵控,經(jīng)常和FLAG_ACTIVITY_NEW_DOCUMENT或者FLAG_ACTIVITY_NEW_TASK一起使用香到。這上面兩種使用場景下,如果沒有帶上FLAG_ACTIVITY_MULTIPLE_TASK標(biāo)識报破,他們都會使系統(tǒng)搜索存在的task棧悠就,去尋找匹配intent的一個activity,如果沒有找到就會去新建一個task棧充易;但是當(dāng)和FLAG_ACTIVITY_MULTIPLE_TASK一起使用的時候梗脾,這兩種場景都會跳過搜索這步操作無條件的創(chuàng)建一個新的task。和FLAG_ACTIVITY_NEW_TASK一起使用需要注意盹靴,盡量不要使用該組合除非你完成了自己的頂部應(yīng)用啟動器炸茧,他們的組合使用會禁用已經(jīng)存在的task棧回到前臺的功能稿静。?
api 21之后加入的一個標(biāo)識梭冠,用來在intent啟動的activity的task棧中打開一個document,和documentLaunchMode效果相等改备,有著不同的documents的activity的多個實例控漠,將會出現(xiàn)在最近的task列表中。單獨使用效果和documentLaunchMode=”intoExisting”一樣悬钳,如果和FLAG_ACTIVITY_MULTIPLE_TASK一起使用效果就等同于documentLaunchMode=”always”润脸。?
設(shè)置此狀態(tài),記住以下原則他去,首先會查找是否存在和被啟動的Activity具有相同的親和性的任務(wù)棧(即taskAffinity毙驯,注意同一個應(yīng)用程序中的activity的親和性在沒有修改的情況下是一樣的,所以下面的a情況會在同一個棧中)灾测,如果有爆价,剛直接把這個棧整體移動到前臺垦巴,并保持棧中的狀態(tài)不變,即棧中的activity順序不變铭段,如果沒有骤宣,則新建一個棧來存放被啟動的activity。?
a. 前提: Activity A和Activity B在同一個應(yīng)用中序愚。?
操作: Activity A啟動開僻Task堆棧(堆棧狀態(tài):A)憔披,在Activity A中啟動Activity B, 啟動Activity B的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK爸吮,Activity B被壓入Activity A所在堆棧(堆棧狀態(tài):AB)芬膝。?
原因: 默認(rèn)情況下同一個應(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啟動開僻Task堆棧桐早,命名為TaskA(TaskA堆棧狀態(tài): A)癣缅,在Activity A中啟動Activity C, 啟動Activity C的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK哄酝,Android系統(tǒng)會為Activity C開僻一個新的Task友存,命名為TaskB(TaskB堆棧狀態(tài): C), 長按Home鍵,選擇TaskA陶衅,Activity A回到前臺, 再次啟動Activity C(兩種情況:1.從桌面啟動爬立;2.從Activity A啟動,兩種情況一樣)万哪, 這時TaskB回到前臺, Activity C顯示侠驯,供用戶使用, 即:包含F(xiàn)LAG_ACTIVITY_NEW_TASK的Intent啟動Activity的Task正在運行,則不會為該Activity創(chuàng)建新的Task奕巍,而是將原有的Task返回到前臺顯示吟策。
操作2:在Launcher中單擊”TaskOne應(yīng)用”圖標(biāo),Activity A啟動開僻Task堆棧的止,命名為TaskA(TaskA堆棧狀態(tài): A)檩坚,在Activity A中啟動Activity C,啟動Activity C的Intent的Flag設(shè)為FLAG_ACTIVITY_NEW_TASK诅福,Android系統(tǒng)會為Activity C開僻一個新的Task匾委,命名為TaskB(TaskB堆棧狀態(tài): C), 在Activity C中啟動Activity D(TaskB的狀態(tài): CD) 長按Home鍵氓润, 選擇TaskA赂乐,Activity A回到前臺, 再次啟動Activity C(從桌面或者ActivityA啟動咖气,也是一樣的)挨措,這時TaskB回到前臺, Activity D顯示挖滤,供用戶使用。說明了在此種情況下設(shè)置FLAG_ACTIVITY_NEW_TASK后浅役,會先查找是不是有Activity C存在的棧斩松,根據(jù)親和性(taskAffinity),如果有觉既,剛直接把這個棧整體移動到前臺惧盹,并保持棧中的狀態(tài)不變,即棧中的順序不變瞪讼。
禁止activity之間的切換動畫?
該Activity將不在stack中保留钧椰,用戶一離開它,這個Activity就關(guān)閉了尝艘。?
禁止activity調(diào)用onUserLeaveHint()函演侯。onUserLeaveHint()作為activity周期的一部分姿染,它在activity因為用戶要跳轉(zhuǎn)到別的activity而退到background時使用背亥。比如,在用戶按下Home鍵(用戶的操作)悬赏,它將被調(diào)用狡汉。比如有電話進來(不屬于用戶的操作),它就不會被調(diào)用闽颇。注意:通過調(diào)用finish()時該activity銷毀時不會調(diào)用該函數(shù)盾戴。?
FLAG_ACTIVITY_PREVIOUS_IS_TOP?
如果給Intent對象設(shè)置了這個標(biāo)記,這個Intent對象被用于從一個存在的Activity中啟動一個新的Activity兵多,那么新的這個Activity不能用于接受發(fā)送給頂層activity的intent尖啡,這個新的activity的前一個activity被作為頂部activity。?
FLAG_ACTIVITY_REORDER_TO_FRONT?
如果在Intent中設(shè)置剩膘,并傳遞給Context.startActivity()衅斩,這個標(biāo)志將引發(fā)已經(jīng)運行的Activity移動到歷史stack的頂端。 例如怠褐,假設(shè)一個Task由四個Activity組成:A畏梆,B,C奈懒,D奠涌。如果D調(diào)用startActivity()來啟動Activity B,那么磷杏,B會移動到歷史stack的頂端溜畅,現(xiàn)在的次序變成A,C极祸,D达皿,B天吓。如果FLAG_ACTIVITY_CLEAR_TOP標(biāo)志也設(shè)置的話,那么這個標(biāo)志將被覆蓋峦椰。?
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED?
這個標(biāo)記在以下情況下會生效:1.啟動Activity時創(chuàng)建新的task來放置Activity實例龄寞;2.已存在的task被放置于前臺。系統(tǒng)會根據(jù)affinity對指定的task進行重置操作汤功,task會壓入某些Activity實例或移除某些Activity實例物邑。我們結(jié)合上面的FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET可以加深理解。?
FLAG_ACTIVITY_RETAIN_IN_RECENTS?
api21加入滔金。?
默認(rèn)情況下通過FLAG_ACTIVITY_NEW_DOCUMENT啟動的activity在關(guān)閉之后色解,task中的記錄會相對應(yīng)的刪除。如果為了能夠重新啟動這個activity你想保留它餐茵,就可以使用者個flag科阎,最近的記錄將會保留在接口中以便用戶去重新啟動。接受該flag的activity可以使用autoRemoveFromRecents去復(fù)寫這個request或者調(diào)用Activity.finishAndRemoveTask()方法忿族。?
singleTop一樣?
api11加入锣笨。?
把當(dāng)前新啟動的任務(wù)置于Home任務(wù)之上,也就是按back鍵從這個任務(wù)返回的時候會回到home道批,即使這個不是他們最后看見的activity错英,注意這個標(biāo)記必須和FLAG_ACTIVITY_NEW_TASK一起使用。?
將log置為可用狀態(tài)隆豹,如果設(shè)置了這個flag椭岩,那么在處理這個intent的時候,將會打印相關(guān)創(chuàng)建日志璃赡。?
FLAG_EXCLUDE_STOPPED_PACKAGES和FLAG_INCLUDE_STOPPED_PACKAGES?
在3.1之后判哥,系統(tǒng)的package manager增加了對處于“stopped state”應(yīng)用的管理,這個stopped和Activity生命周期中的stop狀態(tài)是完全兩碼事碉考,指的是安裝后從來沒有啟動過和被用戶手動強制停止的應(yīng)用塌计,與此同時系統(tǒng)增加了2個Flag:FLAG_INCLUDE_STOPPED_PACKAGES和FLAG_EXCLUDE_STOPPED_PACKAGES ,來標(biāo)識一個intent是否激活處于“stopped state”的應(yīng)用豆励。當(dāng)2個Flag都不設(shè)置或者都進行設(shè)置的時候夺荒,采用的是FLAG_INCLUDE_STOPPED_PACKAGES的效果。?
用來標(biāo)識該intent的操作是一個后端的操作而不是一個直接的用戶交互良蒸。?
FLAG_GRANT_PERSISTABLE_URI_PERMISSION?
api19添加?
當(dāng)和FLAG_GRANT_READ_URI_PERMISSION 和/或FLAG_GRANT_WRITE_URI_PERMISSION一起使用時技扼,uri權(quán)限在設(shè)置重啟之后依然存在直到用戶調(diào)用了revokeUriPermission(Uri, int)方法,這個標(biāo)識僅為可能的存在狀態(tài)提供許可嫩痰,接受的應(yīng)用必須要調(diào)用takePersistableUriPermission(Uri, int)方法去實際的變?yōu)榇嬖跔顟B(tài)剿吻。?
FLAG_GRANT_PREFIX_URI_PERMISSION?
api21加入。?
當(dāng)和FLAG_GRANT_READ_URI_PERMISSION 和/或FLAG_GRANT_WRITE_URI_PERMISSION一起使用時串纺,uri的許可只用匹配前綴即可(默認(rèn)為全部匹配)丽旅。?
FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION?
如果設(shè)置FLAG_GRANT_READ_URI_PERMISSION這個標(biāo)記,Intent的接受者將會被賦予讀取Intent中URI數(shù)據(jù)的權(quán)限和lipData中的URIs的權(quán)限椰棘。當(dāng)使用于Intent的ClipData時,所有的URIs和data的所有遞歸遍歷或者其他Intent的ClipData數(shù)據(jù)都會被授權(quán)榄笙。FLAG_GRANT_WRITE_URI_PERMISSION同F(xiàn)LAG_GRANT_READ_URI_PERMISSION只是相應(yīng)的賦予的是寫權(quán)限邪狞。?
一個典型的例子就是郵件程序處理帶有附件的郵件。進入郵件需要使用permission來保護茅撞,因為這些是敏感的用戶數(shù)據(jù)帆卓。然而,如果有一個指向圖片附件的URI需要傳遞給圖片瀏覽器米丘,那個圖片瀏覽器是不會有訪問附件的權(quán)利的剑令,因為他不可能擁有所有的郵件的訪問權(quán)限。針對這個問題的解決方案就是per-URI permission:當(dāng)啟動一個activity或者給一個activity返回結(jié)果的時候拄查,呼叫方可以設(shè)置Intent.FLAG_GRANT_READ_URI_PERMISSION和/或Intent.FLAG_GRANT_WRITE_URI_PERMISSION . 這會使接收該intent的activity獲取到進入該Intent指定的URI的權(quán)限吁津,而不論它是否有權(quán)限進入該intent對應(yīng)的content provider。?
api16添加堕扶。?
當(dāng)發(fā)送廣播時碍脏,允許其接受者擁有前臺的優(yōu)先級,更短的超時間隔挣柬。?
api19添加?
如果這是一個有序廣播潮酒,不允許接受者終止這個廣播睛挚,它仍然能夠傳遞給下面的接受者邪蛔。?
FLAG_RECEIVER_REGISTERED_ONLY?
如果設(shè)置了這個flag,當(dāng)發(fā)送廣播的時扎狱,動態(tài)注冊的接受者才會被調(diào)用侧到,在Androidmanifest.xml 里定義的Receiver 是接收不到這樣的Intent 的。?
FLAG_RECEIVER_REPLACE_PENDING?
api8添加淤击。?
如果設(shè)置了的話匠抗,ActivityManagerService就會在當(dāng)前的系統(tǒng)中查看有沒有相同的intent還未被處理,如果有的話污抬,就由當(dāng)前這個新的intent來替換舊的intent汞贸,所以就會出現(xiàn)在發(fā)送一系列的這樣的Intent 之后,中間有些Intent 有可能在你還沒有來得及處理的時候印机, 就被替代掉了的情況
每個Activity都有taskAffinity屬性矢腻,這個屬性指出了它希望進入的Task。如果一個Activity沒有顯式的指明該 Activity的taskAffinity射赛,那么它的這個屬性就等于Application指明的taskAffinity多柑,如果 Application也沒有指明,那么該taskAffinity的值就等于包名楣责。而Task也有自己的affinity屬性竣灌,它的值等于它的根 Activity的taskAffinity的值聂沙。?
TaskAffinity屬性主要和SingleTask啟動模式或者allowTaskReparenting屬性配對使用,在其他情況下沒有意義初嘹。當(dāng)TaskAffinity和singleTask啟動模式配對使用的時候及汉,他是具有該模式的Activity的目前任務(wù)棧的名字,待啟動的Activity會運行在名字和TaskAffinity相同的任務(wù)棧中屯烦。allowTaskReparenting用于配置是否允許該activity可以更換從屬task豁生,通常情況二者連在一起使用,用于實現(xiàn)把一個應(yīng)用程序的Activity移到另一個應(yīng)用程序的Task中漫贞。allowTaskReparenting用來標(biāo)記Activity能否從啟動的Task移動到taskAffinity指定的Task甸箱,默認(rèn)是繼承至application中的allowTaskReparenting=false,如果為true迅脐,則表示可以更換芍殖;false表示不可以。?
如果加載某個Activity的intent谴蔑,F(xiàn)lag被設(shè)置成FLAG_ACTIVITY_NEW_TASK時豌骏,它會首先檢查是否存在與自己taskAffinity相同的Task,如果存在隐锭,那么它會直接宿主到該Task中窃躲,如果不存在則重新創(chuàng)建Task。
http://droidyue.com/blog/2015/08/16/dive-into-android-activity-launchmode/?