什么是Affinity
什么是Affinity
? ?? ? 在某些情況下,Android需要知道一個(gè)Activity屬于哪個(gè)Task,即使它沒有被啟動(dòng)到一個(gè)具體的Task里。這是通過任務(wù)共用性(Affinities)完成的。任務(wù)共用性(Affinities)為這個(gè)運(yùn)行一個(gè)或多個(gè)Activity的Task提供了一個(gè)獨(dú)特的靜態(tài)名稱,默認(rèn)的一個(gè)活動(dòng)的任務(wù)共用性(Affinity)是實(shí)現(xiàn)了該Activity的.apk包的名字。
? ?? ? 當(dāng)開始一個(gè)沒有Intent.FLAG_ACTIVITY_NEW_TASK標(biāo)志的Activity時(shí),任務(wù)共用性affinities不會(huì)影響將會(huì)運(yùn)行該新活動(dòng)的Task:它總是運(yùn)行在啟動(dòng)它的Task里。但是,如果使用了NEW_TASK標(biāo)志,那么共用性(affinity)將被用來判斷是否已經(jīng)存在一個(gè)有相同共用性(affinity)的Task。如果是這樣,這項(xiàng)Task將被切換到前面而新的Activity會(huì)啟動(dòng)于這個(gè)Task的頂層。
? ?? ? 這種特性在您必須使用NEW_TASK標(biāo)志的情況下最有用,尤其是從狀態(tài)欄通知或桌面快捷方式啟動(dòng)活動(dòng)時(shí)。結(jié)果是,當(dāng)用戶用這種方式啟動(dòng)您的應(yīng)用程序時(shí),它的當(dāng)前Task將被切換到前臺(tái),而且想要查看的Activity被放在最上面。
? ?? ? 你可以在程序清單(Manifest)文件的應(yīng)用程序application標(biāo)簽中為.apk包中所有的活動(dòng)分配你自己的任務(wù)共用性Affinites,或者在活動(dòng)標(biāo)記中為各個(gè)活動(dòng)進(jìn)行分配。
? ?? ??一些說明其如何使用的例子如下:
- 如果您的.apk包含多個(gè)用戶可以啟動(dòng)的高層應(yīng)用程序,那么您可能需要對(duì)用戶看到的每個(gè)Activity(活動(dòng))指定不同的affinities。一個(gè)不錯(cuò)的命名慣例是以附加一個(gè)以冒號(hào)分隔的字符串來擴(kuò)展您的.apk包名。例如,“ com.android.contacts ”.apk可以有affinities:“com.android.contacts:Dialer”和“ com.android.contacts:ContactsList”。
- 如果您正在替換一個(gè)通知,快捷方式,或其他可以從外部發(fā)起的應(yīng)用程序的“內(nèi)部”活動(dòng),你可能需要明確設(shè)定您替代活動(dòng)的taskAffinity和您準(zhǔn)備替代的應(yīng)用程序一樣。例如,如果您想替換contacts詳細(xì)信息視圖(用戶可以創(chuàng)建并調(diào)用快捷方式),你得把taskAffinity設(shè)置成“com.android.contacts”。
? ?? ???跟 Task 有關(guān)的 manifest文件中Activity的特性值介紹
? ?? ???android:allowTaskReparenting?
? ?? ???用來標(biāo)記Activity能否從啟動(dòng)的Task移動(dòng)到有著affinity的Task(當(dāng)這個(gè)Task進(jìn)入到前臺(tái)時(shí))
? ?? ? “true”,表示能移動(dòng),“false”,表示它必須呆在啟動(dòng)時(shí)呆在的那個(gè)Task里。
? ?? ? 如果這個(gè)特性沒有被設(shè)定,設(shè)定到<application>元素上的allowTaskReparenting特性的值會(huì)應(yīng)用到Activity上。默認(rèn)值為“false”。
? ?? ? 一般來說,當(dāng)Activity啟動(dòng)后,它就與啟動(dòng)它的Task關(guān)聯(lián),并且在那里耗盡它的整個(gè)生命周期。當(dāng)當(dāng)前的Task不再顯示時(shí),你可以使用這個(gè)特性來強(qiáng)制Activity移動(dòng)到有著affinity的Task中。典型用法是:把一個(gè)應(yīng)用程序的Activity移到另一個(gè)應(yīng)用程序的主Task中。?
? ?? ? 例如,如果 email中包含一個(gè)web頁的鏈接,點(diǎn)擊它就會(huì)啟動(dòng)一個(gè)Activity來顯示這個(gè)頁面。這個(gè)Activity是由Browser應(yīng)用程序定義的,但是,現(xiàn)在它作為email Task的一部分。如果它重新宿主到Browser Task里,當(dāng)Browser下一次進(jìn)入到前臺(tái)時(shí),它就能被看見,并且,當(dāng)email Task再次進(jìn)入前臺(tái)時(shí),就看不到它了。?
? ?? ? Actvity的affinity是由taskAffinity特性定義的。Task的affinity是通過讀取根Activity的affinity決定。因此,根Activity總是位于相同affinity的Task里。由于啟動(dòng)模式為“singleTask”和“singleInstance”的Activity只能位于Task的底部,因此,重新宿主只能限于“standard”和“singleTop”模式。
? ?? ? android:alwaysRetainTaskState
? ?? ? 用來標(biāo)記Activity所在的Task的狀態(tài)是否總是由系統(tǒng)來保持。
? ?? ?“true”,表示總是;“false”,表示在某種情形下允許系統(tǒng)恢復(fù)Task到它的初始化狀態(tài)。默認(rèn)值是“false”。
? ?? ? 這個(gè)特性只針對(duì)Task的根Activity有意義;對(duì)其它Activity來說,忽略之。?
? ?? ? 一般來說,特定的情形如當(dāng)用戶從主畫面重新選擇這個(gè)Task時(shí),系統(tǒng)會(huì)對(duì)這個(gè)Task進(jìn)行清理(從stack中刪除位于根Activity之上的所有Activivity)。典型的情況,當(dāng)用戶有一段時(shí)間沒有訪問這個(gè)Task時(shí)也會(huì)這么做,例如30分鐘。?
? ?? ? 然而,當(dāng)這個(gè)特性設(shè)為“true”時(shí),用戶總是能回到這個(gè)Task的最新狀態(tài),無論他們是如何啟動(dòng)的。這非常有用,例如,像Browser應(yīng)用程序,這里有很多的狀態(tài)(例如多個(gè)打開的Tab),用戶不想丟失這些狀態(tài)。
? ?? ? android:clearTaskOnLaunch
? ?? ? 用來標(biāo)記是否從Task中清除所有的Activity,除了根Activity外(每當(dāng)從主畫面重新啟動(dòng)時(shí))
? ?? ?“true”,表示總是清除至它的根Activity,“false”表示不。默認(rèn)值是“false”。
? ?? ???這個(gè)特性只對(duì)啟動(dòng)一個(gè)新的Task的Activity(根Activity)有意義;對(duì)Task中其它的Activity忽略。?
? ?? ???當(dāng)這個(gè)值為“true”,每次用戶重新啟動(dòng)這個(gè)Task時(shí),都會(huì)進(jìn)入到它的根Activity中,不管這個(gè)Task最后在做些什么,也不管用戶是使用BACK還是HOME離開的。當(dāng)這個(gè)值為“false”時(shí),可能會(huì)在一些情形下(參考alwaysRetainTaskState特性)清除Task的Activity,但不總是。
? ?? ? 假設(shè),某人從主畫面啟動(dòng)了Activity P,并從那里遷移至Activity Q。接下來用戶按下HOME,然后返回Activity P。一般,用戶可能見到的是Activity Q,因?yàn)樗荘的Task中最后工作的內(nèi)容。然而,如果P設(shè)定這個(gè)特性為“true”,當(dāng)用戶按下HOME并使這個(gè)Task再次進(jìn)入前臺(tái)時(shí),其上的所有的Activity(在這里是Q)都將被清除。因此,當(dāng)返回到這個(gè)Task時(shí),用戶只能看到P。
? ?? ? 如果這個(gè)特性和allowTaskReparenting都設(shè)定為“true”,那些能重新宿主的Activity會(huì)移動(dòng)到共享affinity的Task中;剩下的Activity都將被拋棄,如上所述。?
? ?? ? android:finishOnTaskLaunch?
? ??
? ?? ? 用來標(biāo)記當(dāng)用戶再次啟動(dòng)它的Task(在主畫面選擇這個(gè)Task)時(shí)已經(jīng)存在的Activity實(shí)例是否要關(guān)閉(結(jié)束)
? ???“true”,表示應(yīng)該關(guān)閉,“false”表示不關(guān)閉。默認(rèn)值是“false”。?
? ?? ? 如果這個(gè)特性和allowTaskReparenting都設(shè)定為“true”,這個(gè)特性勝出。Activity的affinity忽略。這個(gè)Activity不會(huì)重新宿主,但是會(huì)銷毀。?
?跟 Task 有關(guān)的 Intent對(duì)象中設(shè)置的Flag
? ?? ??FLAG_ACTIVITY_BROUGHT_TO_FRONT?
? ?? ? 這個(gè)標(biāo)志一般不是由程序代碼設(shè)置的,如在launchMode中設(shè)置singleTask模式時(shí)系統(tǒng)幫你設(shè)定。?
? ?? ??FLAG_ACTIVITY_CLEAR_TOP?
? ?? ? 如果設(shè)置,并且這個(gè)Activity已經(jīng)在當(dāng)前的Task中運(yùn)行,因此,不再是重新啟動(dòng)一個(gè)這個(gè)Activity的實(shí)例,而是在這個(gè)Activity上方的所有Activity都將關(guān)閉,然后這個(gè)Intent會(huì)作為一個(gè)新的Intent投遞到老的Activity(現(xiàn)在位于頂端)中。?
? ?? ? 例如,假設(shè)一個(gè)Task中包含這些Activity:A,B,C,D。如果D調(diào)用了startActivity(),并且包含一個(gè)指向Activity B的Intent,那么,C和D都將結(jié)束,然后B接收到這個(gè)Intent,因此,目前stack的狀況是:A,B。?
? ?? ? 上例中正在運(yùn)行的Activity B既可以在onNewIntent()中接收到這個(gè)新的Intent,也可以把自己關(guān)閉然后重新啟動(dòng)來接收這個(gè)Intent。如果它的啟動(dòng)模式聲明為“multiple”(默認(rèn)值),并且你沒有在這個(gè)Intent中設(shè)置FLAG_ACTIVITY_SINGLE_TOP標(biāo)志,那么它將關(guān)閉然后重新創(chuàng)建;對(duì)于其它的啟動(dòng)模式,或者在這個(gè)Intent中設(shè)置FLAG_ACTIVITY_SINGLE_TOP標(biāo)志,都將把這個(gè)Intent投遞到當(dāng)前這個(gè)實(shí)例的onNewIntent()中。?
? ?? ? 這個(gè)啟動(dòng)模式還可以與FLAG_ACTIVITY_NEW_TASK結(jié)合起來使用:用于啟動(dòng)一個(gè)Task中的根Activity,它會(huì)把那個(gè)Task中任何運(yùn)行的實(shí)例帶入前臺(tái),然后清除它直到根Activity。這非常有用,例如,當(dāng)從Notification Manager處啟動(dòng)一個(gè)Activity。
? ?????FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
? ?? ? 如果設(shè)置,這將在Task的Activity stack中設(shè)置一個(gè)還原點(diǎn),當(dāng)Task恢復(fù)時(shí),需要清理Activity。也就是說,下一次Task帶著FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標(biāo)記進(jìn)入前臺(tái)時(shí)(典型的操作是用戶在主畫面重啟它),這個(gè)Activity和它之上的都將關(guān)閉,以至于用戶不能再返回到它們,但是可以回到之前的Activity。?
? ?? ? 這在你的程序有分割點(diǎn)的時(shí)候很有用。例如,一個(gè)e-mail應(yīng)用程序可能有一個(gè)操作是查看一個(gè)附件,需要啟動(dòng)圖片瀏覽Activity來顯示。這個(gè)Activity應(yīng)該作為e-mail應(yīng)用程序Task的一部分,因?yàn)檫@是用戶在這個(gè)Task中觸發(fā)的操作。然而,當(dāng)用戶離開這個(gè)Task,然后從主畫面選擇e-mail app,我們可能希望回到查看的會(huì)話中,但不是查看圖片附件,因?yàn)檫@讓人困惑。通過在啟動(dòng)圖片瀏覽時(shí)設(shè)定這個(gè)標(biāo)志,瀏覽及其它啟動(dòng)的Activity在下次用戶返回到mail程序時(shí)都將全部清除。
? ?? ??FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
? ?? ? 如果設(shè)置,新的Activity不會(huì)在最近啟動(dòng)的Activity的列表中保存。
? ?? ??FLAG_ACTIVITY_FORWARD_RESULT
? ?? ? 如果設(shè)置,并且這個(gè)Intent用于從一個(gè)存在的Activity啟動(dòng)一個(gè)新的Activity,那么,這個(gè)作為答復(fù)目標(biāo)的Activity將會(huì)傳到這個(gè)新的Activity中。這種方式下,新的Activity可以調(diào)用setResult(int),并且這個(gè)結(jié)果值將發(fā)送給那個(gè)作為答復(fù)目標(biāo)的Activity。
? ?? ??FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
? ?? ? 這個(gè)標(biāo)志一般不由應(yīng)用程序代碼設(shè)置,如果這個(gè)Activity是從歷史記錄里啟動(dòng)的(常按HOME鍵),那么,系統(tǒng)會(huì)幫你設(shè)定。
? ?? ??FLAG_ACTIVITY_MULTIPLE_TASK
? ?? ? 不要使用這個(gè)標(biāo)志,除非你自己實(shí)現(xiàn)了應(yīng)用程序啟動(dòng)器。與FLAG_ACTIVITY_NEW_TASK結(jié)合起來使用,可以禁用把已存的Task送入前臺(tái)的行為。當(dāng)設(shè)置時(shí),新的Task總是會(huì)啟動(dòng)來處理Intent,而不管這是是否已經(jīng)有一個(gè)Task可以處理相同的事情。?
? ?? ? 由于默認(rèn)的系統(tǒng)不包含圖形Task管理功能,因此,你不應(yīng)該使用這個(gè)標(biāo)志,除非你提供給用戶一種方式可以返回到已經(jīng)啟動(dòng)的Task。?
? ?? ? 如果FLAG_ACTIVITY_NEW_TASK標(biāo)志沒有設(shè)置,這個(gè)標(biāo)志被忽略。
? ?? ??FLAG_ACTIVITY_NEW_TASK
? ?? ? 如果設(shè)置,這個(gè)Activity會(huì)成為歷史stack中一個(gè)新Task的開始。一個(gè)Task(從啟動(dòng)它的Activity到下一個(gè)Task中的Activity)定義了用戶可以遷移的Activity原子組。Task可以移動(dòng)到前臺(tái)和后臺(tái);在某個(gè)特定Task中的所有Activity總是保持相同的次序。?
? ?? ? 這個(gè)標(biāo)志一般用于呈現(xiàn)“啟動(dòng)”類型的行為:它們提供用戶一系列可以單獨(dú)完成的事情,與啟動(dòng)它們的Activity完全無關(guān)。?
? ?? ? 使用這個(gè)標(biāo)志,如果正在啟動(dòng)的Activity的Task已經(jīng)在運(yùn)行的話,那么,新的Activity將不會(huì)啟動(dòng);代替的,當(dāng)前Task會(huì)簡(jiǎn)單的移入前臺(tái)。參考FLAG_ACTIVITY_MULTIPLE_TASK標(biāo)志,可以禁用這一行為。?
? ?? ? 這個(gè)標(biāo)志不能用于調(diào)用方對(duì)已經(jīng)啟動(dòng)的Activity請(qǐng)求結(jié)果。
? ?? ???FLAG_ACTIVITY_NO_ANIMATION
? ?? ???如果在Intent中設(shè)置,并傳遞給Context.startActivity()的話,這個(gè)標(biāo)志將阻止系統(tǒng)進(jìn)入下一個(gè)Activity時(shí)應(yīng)用Acitivity遷移動(dòng)畫。這并不意味著動(dòng)畫將永不運(yùn)行——如果另一個(gè)Activity在啟動(dòng)顯示之前,沒有指定這個(gè)標(biāo)志,那么,動(dòng)畫將被應(yīng)用。這個(gè)標(biāo)志可以很好的用于執(zhí)行一連串的操作,而動(dòng)畫被看作是更高一級(jí)的事件的驅(qū)動(dòng)。
? ?? ??FLAG_ACTIVITY_NO_HISTORY
? ?? ? 如果設(shè)置,新的Activity將不再歷史stack中保留。用戶一離開它,這個(gè)Activity就關(guān)閉了。這也可以通過設(shè)置noHistory特性。
? ?? ??FLAG_ACTIVITY_NO_USER_ACTION?
? ?? ? 如果設(shè)置,作為新啟動(dòng)的Activity進(jìn)入前臺(tái)時(shí),這個(gè)標(biāo)志將在Activity暫停之前阻止從最前方的Activity回調(diào)的onUserLeaveHint()。?
? ?? ? 典型的,一個(gè)Activity可以依賴這個(gè)回調(diào)指明顯式的用戶動(dòng)作引起的Activity移出后臺(tái)。這個(gè)回調(diào)在Activity的生命周期中標(biāo)記一個(gè)合適的點(diǎn),并關(guān)閉一些Notification。?
? ?? ? 如果一個(gè)Activity通過非用戶驅(qū)動(dòng)的事件,如來電或鬧鐘,啟動(dòng)的,這個(gè)標(biāo)志也應(yīng)該傳遞給Context.startActivity,保證暫停的Activity不認(rèn)為用戶已經(jīng)知曉其Notification。?
? ?? ???FLAG_ACTIVITY_REORDER_TO_FRONT
? ?? ? 如果在Intent中設(shè)置,并傳遞給Context.startActivity(),這個(gè)標(biāo)志將引發(fā)已經(jīng)運(yùn)行的Activity移動(dòng)到歷史stack的頂端。?
? ?? ? 例如,假設(shè)一個(gè)Task由四個(gè)Activity組成:A,B,C,D。如果D調(diào)用startActivity()來啟動(dòng)Activity B,那么,B會(huì)移動(dòng)到歷史stack的頂端,現(xiàn)在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標(biāo)志也設(shè)置的話,那么這個(gè)標(biāo)志將被忽略。?
? ?? ??FLAG_ACTIVITY_SINGLE_TOP
? ?? ? 如果設(shè)置,當(dāng)這個(gè)Activity位于歷史stack的頂端運(yùn)行時(shí),不再啟動(dòng)一個(gè)新的。
總結(jié)
以上是生活随笔為你收集整理的什么是Affinity的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux链接达梦数据库,linux下面
- 下一篇: 共同富裕、乡村振兴专题:基尼系数、恩格尔