APP開發實戰60-Activity啟動FLAG

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容