Android Intent的FLAG標志詳解
在Android開發中,Intent想必大家經常用。Intent本意為目的、意向、意圖。在Android中,Intent是系統各組件(或應用程序)之間進行數據傳遞的數據附載者,Intent不僅可以用于應用程序之間的交互,也可以用于應用程序內部的Activity、Service和Broadcast Receiver之間的交互。 解讀Android Intent 。本文主要說的是Intent的Flag標志。
Task
Task就是一個任務棧,里面用來存放Activity,第一個進去的(Activity)處于棧的最下面,而最后創建的(Activity)則處于棧的最上面。從Task中取出(Activity)是從最頂端取出,也就是說先進后出,后進先出。而Activity在Task中的順序是可以控制的,在Activity跳轉時用到Intent Flag可以設置新建Activity的創建方式。
FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個Flag的意思,比如我現在有一個A,然后在A中啟動B,并設置FLAG_ACTIVITY_BROUGHT_TO_FRONT這個啟動標記,那么B就是以FLAG_ACTIVITY_BROUGHT_TO_FRONT啟動的。然后在B中啟動C,此時棧就是A,B,C。如果這個時候在C中啟動B,那么棧的情況會是A,C,B。
FLAG_ACTIVITY_REORDER_TO_FRONT
如果在棧中有A,B,C三個Activity,并且是正常啟動的,此時在C中啟動B的話,還是會變成A,C,B的。 如果使用了標志 FLAG_ACTIVITY_CLEAR_TOP,那這個FLAG_ACTIVITY_REORDER_TO_FRONT標志會被忽略。
FLAG_ACTIVITY_NEW_TASK
假設現在有一個棧1,里面是A,B,C。此時,在C中啟動D的時候,設置FLAG_ACTIVITY_NEW_TASK標記,此時會有兩種情況:
1.如果D這個Activity在Manifest.xml中的聲明中添加了Task Affinity,系統首先會查找有沒有和D的Task Affinity相同的Task棧存在,如果有存在,將D壓入那個棧 2.如果D這個Activity在Manifest.xml中的Task Affinity默認沒有設置,則會把其壓入棧1,變成:A B C D,這樣就和標準模式效果是一樣的了。
也就是說,設置了這個標志后,新啟動的Activity并非就一定在新的Task中創建,如果A和B在屬于同一個package,而且都是使用默認的Task Affinity,那B還是會在A的task中被創建。 所以,只有A和B的Task Affinity不同時,設置了這個標志才會使B被創建到新的Task。注意如果試圖從非Activity的非正常途徑啟動一個Activity,比如從一個Receiver中啟動一個Activity,則Intent必須要添加FLAG_ACTIVITY_NEW_TASK標記。
FLAG_ACTIVITY_CLEAR_TASK
如果Intent中設置了這個標志,會導致含有待啟動Activity的Task在Activity被啟動前清空。也就是說,這個Activity會成為一個新的root,并且所有舊的activity都被finish掉。這個標志只能與FLAG_ACTIVITY_NEW_TASK 一起使用。
FLAG_ACTIVITY_SINGLE_TOP
這個FLAG就相當于加載模式中的singleTop,比如說原來棧中情況是A,B,C,D在D中啟動D,棧中的情況還是A,B,C,D。
FLAG_ACTIVITY_CLEAR_TOP
這個FLAG就相當于加載模式中的SingleTask,如果啟動的Activity存在當前的棧中,系統會把要啟動的Activity之上的Activity全部彈出棧空間,然后把Intent作為一個新的Intent傳給這個Activity。
例如:原來棧中的情況是A,B,C,D這個時候從D中跳轉到B,這個時候棧中的情況就是A,B了。上面例子中運行的B activity既可以在onNewIntent()中接收新的Intent,也可以將自己finish掉然后使用新的Intent重啟。如果在它的launch mode中設置了"multiple"(默認),并且intent中沒有設置 FLAG_ACTIVITY_SINGLE_TOP 標志,那它就會被finish掉然后重新創建。如果是其它的launchMode或者是設置了FLAG_ACTIVITY_SINGLE_TOP 屬性,那就會使用現有的實例的OnNewIntent()方法來接受Intent。
這種啟動模式也可以與 FLAG_ACTIVITY_NEW_TASK 一起使用:如果用來啟動一個任務的root activity,它會將這個任務中現在運行的實例調到前臺,然后將任務清空至只有根Activity的狀態。這很有用,例如要從通知中心里啟動一個Activity時。
FLAG_ACTIVITY_NO_HISTORY
用這個FLAG啟動的Activity,一但退出,就不會存在于棧中。棧中是A,B,C 這個時候再C中以這個FLAG啟動D的,D再啟動E,這個時候棧中情況為A,B,C,E。簡而言之,跳轉到的activity不壓在棧中。
FLAG_ACTIVITY_NO_USER_ACTION
如果設置了這個標志,可以在避免用戶離開當前Activity時回調到 onUserLeaveHint()。通常,Activity可以通過這個回調表明有明確的用戶行為將當前Activity切出前臺。這個回調標記了Activity生命周期中的一個恰當的點,可以用來“在用戶看過通知之后”將它們清除,如閃爍LED燈。
如果Activity是由非用戶驅動的事件(如電話呼入或鬧鐘響鈴)啟動的,那這個標志就應該被傳入Context.startActivity,以確保被打斷的Activity不會認為用戶已經看過了通知。
以下內容是根據文檔和網上查看的FLAG(目的是為了把FLAG總結在一起)
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
設置這個標志意味著在activity棧中做一個標記,在Task重置的時候棧就把從標記往上的activity都清除。也就是說,下次這個Task被通過FLAG_ACTIVITY_RESET_TASK_IF_NEEDED調到前臺時(通常是由于用戶從桌面重新啟動),這個activity和它之上的activity都會被finish掉,這樣用戶就不會再回到他們,而是直接回到在它們之前的activity。
這在應用切換時非常有用。比如,Email應用會需要查看附件,就要調用查看圖片的Activity來顯示,那這個查看圖片的Activity就會成為Email應用任務里的一部分。但是,如果用戶離開了Email的任務,過了一會兒由通過Home來選擇Email應用,我們會希望它回到查看郵件會話的頁面,而不是瀏覽圖片附件的頁面,不然就感覺太詭異了。如果在啟動查看圖片Activity時設置了這個標志,那這個Activity及由它啟動的Activity在下一次用戶返回郵件時都會被清除。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果設置這個標志,這個Activity就不會在近期任務中顯示。
FLAG_ACTIVITY_FORWARD_RESULT
如果Activity A 在啟動 Activity B時設置了這個標志,那A的答復目標目標會傳遞給B,這樣一來B就可以通過調用setResult(int) 將返回結果返回給A的答復目標。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
這個標志通常情況下不會通過應用的代碼來設置,而是在通過最近任務啟動activity時由系統設置的。
FLAG_ACTIVITY_NO_ANIMATION
禁用掉系統默認的Activity切換動畫。
FLAG_ACTIVITY_TASK_ON_HOME
這個標志可以將一個新啟動的任務置于當前的home任務(home activity task)之上(如果有的話)。也就是說,在任務中按back鍵總是會回到home界面,而不是回到他們之前看到的activity。這個標志只能與FLAG_ACTIVITY_NEW_TASK標志一起用。
比如,A->B->C->D,如果在C啟動D的時候設置了這個標志,那在D中按Back鍵則是直接回到桌面,而不是C。
注意:只有D是在新的task中被創建時(也就是D的launchMode是singleInstance時,或者是給D指定了與C不同的taskAffinity并且加了FLAG_ACTIVITY_NEW_TASK標志時),使用 FLAG_ACTIVITY_TASK_ON_HOME標志才會生效。
感覺實際使用效果和用 FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK 的效果一樣。
FLAG_FROM_BACKGROUND
可以給調用者用來標識這個Intent是來自后臺操作,而不是用戶的交互行為。
FLAG_RECEIVER_FOREGROUND
當發送廣播的時候設置了這個標志,會允許接收者以前臺的優先級運行,有更短的時間間隔。正常廣播的接受者是后臺優先級,不會被自動提升。
FLAG_RECEIVER_REPLACE_PENDING
如果在發送廣播時設置了這個標志,那新的廣播會替換掉那些已存在的相同廣播。相同的定義是通過Intent.filterEquals方法對兩個廣播的Intent處理返回true。 當匹配到相同的,新的廣播和對應的接收器會將待發送的廣播列表中已存在的替換掉,在列表中保留同樣的位置。這個標志通常被粘性廣播(Sticky Broadcast)使用,只保證將最新的廣播的值傳遞給接收器。
來自:http://www.jianshu.com/p/537aa221eec4