16.1.2FLAG介紹
在代碼里面通過Intent啟動Activity的時候可以添加flag,如 :
intent.addFlags(Intent.FLAG_ACTIVITY_XXX);
FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個標志一般不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統幫你設定。
FLAG_ACTIVITY_CLEAR_TASK
此Activity將變成一個新Task中新的最底端的Activity,所有的之前此Activity實例和包含該實例的Task都會被關閉,這個標識僅僅和FLAG_ACTIVITY_NEW_TASK聯合起來才能使用。
FLAG_ACTIVITY_NEW_TASK
與launchMode="singleTask"一樣的效果。
FLAG_ACTIVITY_CLEAR_TOP
清除包含此Activity的Task中位于該Activity實例之上的其他Activity實例。這種行為的 launchMode 屬性沒有對應的值,只能通過代碼設置。
單獨使用的情況:ABCD 啟動 B ,會銷毀B和B以上的實例 變成 AB ,B 重新執行onCreate-> onStart
配合FLAG_ACTIVITY_SINGLE_TOP使用,則 B 不會銷毀只銷毀B以上實例,然后B 執行onNewIntent ->onStart
配合FLAG_ACTIVITY_NEW_TASK則是singleTask效果。
FLAG_ACTIVITY_SINGLE_TOP
與launchMode="singleTop"一樣的效果。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
設置了的話,該Activity則不出現在最近使用的列表中。
FLAG_ACTIVITY_FORWARD_RESULT
如果A需要onActivityResult中獲取返回結果,startActivityForResult B,而B只是過渡頁,啟動C之后就finish掉了,需要在 C 中setResult返回給A就可以用到這個標志。
A -> B-> XXXX(無論多少個過渡頁)設置FLAG_ACTIVITY_FORWARD_RESULT 來啟動 C ,之后該XXX過渡頁finish - > C ,那么C的結果返回給A。
FLAG_ACTIVITY_NO_HISTORY
如果設置,新的Activity將不再歷史stack中保留。用戶一離開它,這個Activity就關閉了。
例如A啟動B的時候,給B設置了FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,那么:
A-> B -> C ,啟動C 就算 B沒有自行finish ,也會變為 AC。
FLAG_ACTIVITY_NO_ANIMATION
啟動的時候不執行動畫。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
當用戶點擊Home,從歷史中選擇該Activity,系統會自動加上這個Flag。
FLAG_ACTIVITY_NO_USER_ACTION
在onPause()之前會調用onUserLeaving( )方法,如果使用了該標識,說明目標Activity不和用戶交互,所以也就不需要回調onUserLeaving()方法。
FLAG_ACTIVITY_REORDER_TO_FRONT
如果設置這個標記,新啟動的Activity將會被放到它所屬task的最前面。
例如,假如有一個Task包含4個Activity:A,B,C,D.如果D通過調用startActivity( )來啟動B,如果使用了這個標記,B將會排在這個task的最上面,也即現在的順序變成了A,C,D,B。
如果使用了FLAG_ACTIVITY_CLEAR_TOP,這個標記將會被忽略。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
如果設置該屬性,并且這個Activity在一個新的Task中正在被啟動或者被帶到一個已經存在的Task的頂部,這時這個Task會被重置(即該Task中之前的Activity會被關閉),該Activity成為棧底第一個Activity。
FLAG_ACTIVITY_TASK_ON_HOME
把當前新啟動的任務置于Home任務之上,也就是按back鍵從這個任務返回的時候會回到Home,即使這個不是他們最后看見的Activity。
注意這個標記必須和FLAG_ACTIVITY_NEW_TASK加上Android:taskAffinity一起使用。
FLAG_DEBUG_LOG_RESOLUTION
用來調試,當設置這個標志的時候,在解析這個intent的時候,將會打出打印信息(queryIntent函數)。
FLAG_INCLUDE_STOPPED_PACKAGES
FLAG_EXCLUDE_STOPPED_PACKAGES
從Android 3.1開始,給Intent定義了兩個新的Flag,分別為FLAG_INCLUDE_STOPPED_PACKAGES
和FLAG_EXCLUDE_STOPPED_PACKAGES,用來控制Intent是否要對處于停止狀態的App起作用,顧名思義:
FLAG_INCLUDE_STOPPED_PACKAGES:表示包含未啟動的App
FLAG_EXCLUDE_STOPPED_PACKAGES:表示不包含未啟動的App
值得注意的是,Android 3.1開始,系統向所有Intent的廣播添加了FLAG_EXCLUDE_STOPPED_PACKAGES標志。這樣做是為了防止廣播無意或不必要地開啟未啟動App的后臺服務。如果要強制調起未啟動的App,后臺服務或應用程序可以通過向廣播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES標志來喚醒。
FLAG_FROM_BACKGROUND
Intent不光可以在Acitivity里面start,還可以從service里面啟動,這個參數就表示這個Intent是從后臺服務發起的。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
區別于FLAG_GRANT_READ_URI_PERMISSION 跟FLAG_GRANT_WRITE_URI_PERMISSION, URI權限會持久存在即使重啟,直到明確的用revokeUriPermission(Uri, int) 撤銷。 這個flag只提供可能持久授權。但是接收的應用必須調用ContentResolver的takePersistableUriPermission(Uri,int)方法實現 。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
Uri 權限授予任何原始授權URI前綴匹配的URI。
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
結合FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION 使用。
Uri 權限授予任何原始授權URI前綴匹配的URI。如果沒有這個標志則必須精確匹配Uri了。
FLAG_GRANT_READ_URI_PERMISSION
FLAG_GRANT_WRITE_URI_PERMISSION
臨時訪問讀權限和寫權限 。Intent的接受者將被授予 INTENT 數據 uri 或者 在ClipData 上的讀/寫權限。
FLAG_RECEIVER_FOREGROUND
當發送廣播時,允許其接受者 在前臺運行的擁有更高的優先級,更短的超時間隔。
FLAG_RECEIVER_NO_ABORT
如果是有序廣播,不要允許接收者中斷廣播播。
FLAG_RECEIVER_REGISTERED_ONLY
設置之后就不能通過xml來注冊監聽這個廣播了,必須動態注冊。
很多毒病程序為了證保自己被止終后可以再次行運,都會在xml中冊注一些系統廣播,妄圖利用這些系統高頻廣播來實現自動啟。
比如在老版本的android系統中,毒病程序可以通過監聽TIME_TICK來動啟自己的service后臺行運,做一些秘隱的作工,而且就算自己被kill失落了,也能很快重新動啟。
而一旦這些系統廣播加了flag FLAG_RECEIVER_REGISTERED_ONLY,這些毒病程序就沒轍了。
例如系統的TIME_TICK廣播,由AlarmManagerService發送,我們看源碼可以看到
mTimeTickSender = PendingIntent.getBroadcast(context, 0,
new Intent(Intent.ACTION_TIME_TICK).addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY), 0);
這樣就不能監聽ACTION_TIME_TICK來自啟動了。
FLAG_RECEIVER_REPLACE_PENDING
這個Flag 將會將之前的Intent 替代掉。加了這個Flag,在發送一系列的這樣的Intent 之后,中間有些Intent 有可能在你還沒有來得及處理的時候,就被替代掉了。
FLAG_ACTIVITY_NEW_DOCUMENT(FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
可以跟FLAG_ACTIVITY_MULTIPLE_TASK結合使用,當只用自己的時候相當于Manifast中android.R.attr.documentLaunchMode="intoExisting",當跟FLAG_ACTIVITY_MULTIPLE_TASK結合使用相當于 Manifast中android.R.attr.documentLaunchMode="always"。
FLAG_ACTIVITY_RETAIN_IN_RECENTS
默認情況下通過FLAG_ACTIVITY_NEW_DOCUMENT啟動的Activity在關閉之后,Task中的記錄會相對應的刪除。如果為了能夠重新啟動這個Activity你想保留它,就可以使用者個flag,最近的記錄將會保留在接口中以便用戶去重新啟動。接受該Flag的Activity可以使用autoRemoveFromRecents去復寫這個request或者調用Activity.finishAndRemoveTask()方法。
FLAG_ACTIVITY_MULTIPLE_TASK
這個標識用來創建一個新的task棧,并且在里面啟動新的activity(所有情況,不管系統中存在不存在該activity實例),經常和FLAG_ACTIVITY_NEW_DOCUMENT或者FLAG_ACTIVITY_NEW_TASK一起使用。
這上面兩種使用場景下,如果沒有帶上FLAG_ACTIVITY_MULTIPLE_TASK標識,他們都會使系統搜索存在的task棧,去尋找匹配intent的一個activity,如果沒有找到就會去新建一個task棧;但是當和FLAG_ACTIVITY_MULTIPLE_TASK一起使用的時候,這兩種場景都會跳過搜索這步操作無條件的創建一個新的task。和FLAG_ACTIVITY_NEW_TASK一起使用需要注意,盡量不要使用該組合除非你完成了自己的頂部應用啟動器,他們的組合使用會禁用已經存在的task棧回到前臺的功能。
taskAffinity和 allowTaskReparenting
taskAffinity用于指定當前Activity所關聯的Task,allowTaskReparenting用于配置是否允許該Activity可以更換從屬Task,通常情況二者連在一起使用,用于實現把一個應用程序的Activity移到另一個應用程序的Task中。
allowTaskReparenting用來標記Activity能否從啟動的Task移動到taskAffinity指定的Task,默認是繼承至application中的allowTaskReparenting=false,如果為true,則表示可以更換;false表示不可以。
例如在A應用中啟動了B應用的Activity,如果設置allowTaskReparenting=true,則Activity允許從A的Task移動到B的Task。但如果A被啟動之后,Activity就會回到A的Task中。
原文鏈接:http://www.lxweimin.com/p/7f1c9fac2af2