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