Intent Flag學習筆記


  Intent中有顯示Intent和隱式Intent,顯示Intent一般用於程序內部並且明確Activity的名字,啟動時一般是intent = new Intent(上下文,Activity名字.class);隱式Intent一般用於不同應用程序的交互。開發中經常用到了顯示Intent,而Intent的啟動后的Activity會由系統開啟Task進行管理,以先進后出的形式進行管理,而且默認的管理方式是每次開啟Activity都要進行實例化,那么如果想要改變默認的管理方式,使得其更符合開發的需要,就需要進行某些設置。

下面是我的一些學習筆記:有三個方面,1,Intent Flag部分;2,LaunchMode 部分; 3,Manifest中<activity>屬性

一:Intent Flag部分

  Intent Flag中只是學習那些可以改變Task管理方式的Flag,這個在官方的文檔中有給出詳細的介紹http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_BROUGHT_TO_FRONT

FLAG_ACTIVITY_BROUGHT_TO_FRONT

  這個標識一般不由程序代碼設置,而是當launchMode被設置為singleTask時系統幫你設定的

  前提:Activiy A,B,C,D在“FlagTest應用”中

  場景演示:在Launcher中單擊“FlagTest應用”圖標,Activity A啟動開僻Task堆棧, 命名為TaskA(TaskA堆棧狀態: A),Activity A 啟動 Activity B ,此時Activity B 的launchMode設置為singleTask,Activity B啟動Activity C,Activity C啟動Activity D(TaskA堆棧的狀態為:ABCD),Activity D啟動Activity B,因為Activity B的啟動模式為singleTask,所以系統會為Activity B 設定 FLAG_ACTIVITY_BROUGHT_TO_FRONT,那么這時的TaskA堆棧的狀態為:AB。

FLAG_ACTIVITY_CLEAR_TASK

  如果啟動了設置此標識的intent,那么在activity被啟動之前,這個標識將會使得與此Activity相關聯的任何棧被清空。結果就是,這個activity成為另一個空棧的根activity,而其他老的activity被銷毀。這個只能和FLAG_ACTIVITY_NEW_TASK相結合使用。

FLAG_ACTIVITY_CLEAR_TOP

  如果設置了此標識,並且這個Activity已經運行在當前的棧中,那么不是啟動此Activity的新實例,而是在此Activity上的其他Activity會被銷毀,然后這個intent將會被派發到舊的Activity(此時在棧頂)

  前提:Activity A,B,C,D在同個應用中

  場景演示:Activity A啟動開僻Task堆棧(Task堆棧狀態: A),Activity A 啟動 Activity B,Activity B 設置了FLAG_ACTIVITY_CLEAR_TOP這個標識,Activity B啟動Activity C,Activity C啟動Activity D(TaskA堆棧的狀態為:ABCD),Activity D啟動 Activity B,那么此時C,D則會被銷毀,Task堆棧的狀態:AB。

FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

  如果設置了此標識,這在棧中的Activity標記了一個當棧被重置的時候應該被清除的還原點。就是說,當下次棧攜帶有FLAG_ACTIVITY_RESET_IF_NEEDED標識回到了前台(這是用戶從主界面重啟動的典型結果),那個被設置了還原點的Activity和在這個Activity上的Activity將被銷毀,並且用戶無法返回到他們,但能夠返回到這個Activity之前的

  這個比較適合有分割點的程序。例如:

  場景演示:Activity A啟動開辟了Task堆棧(Task堆棧的狀態為:A),可能在Activity A在要瀏覽圖片而啟動了Activity B來顯示圖片,此時的Task堆棧狀態為:AB,當用戶離開了當前的Task后,再從主頁面啟動該程序,那么顯示的就是該圖片,這就會讓用戶困擾,所以就應該在這個Activity B中設置FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,當重新回到此Task的時候,Activity B就會被銷毀,此時的Task堆棧狀態為:A,那么與用戶交互的就是Activity A而不是讓用戶困擾的圖片。

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  如果設置,新的Activity不會在最近啟動的Activity的列表中保存。

FLAG_ACTIVITY_FORWARD_RESULT

  如果設置,並且這個Intent用於從一個存在的Activity啟動一個新的Activity,那么,這個作為答復目標的Activity將會傳到這個新的Activity中。這種方式下,新的Activity可以調用setResult(int),並且這個結果值將發送給那個作為答復目標的Activity。

  這個Flag與startActivityForResult(intent, requestCode)的效果一樣。

FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

  這個標識一般不由程序代碼設置,而是當Activity在歷史記錄中(長按home鍵)被啟動時系統設置的

FLAG_ACTIVITY_MULTIPLE_TASK

  不要使用這個標志,除非你自己實現了應用程序啟動器。與FLAG_ACTIVITY_NEW_TASK結合起來使用,可以禁用把已存的Task送入前台的行為。當設置時,新的Task總是會啟動來處理Intent,而不管這是是否已經有一個Task可以處理相同的事情。由於默認的系統不包含圖形Task管理功能,因此,你不應該使用這個標志,除非你提供給用戶一種方式可以返回到已經啟動的Task。如果FLAG_ACTIVITY_NEW_TASK標志沒有設置,這個標志被忽略。

FLAG_ACTIVITY_NEW_TASK

  在一個新的棧中啟動這個Activity,如果你將要啟動的Activity已經在一個棧中運行了,那么這個棧將記住它最近的狀態然后被放置到前台,而這個Activity中onNewIntent()中接收這個新的intent,這個與launchMode的singleTask有相同的行為。

  設置此標識,系統首先會查找是否存在和被啟動的Activity具有相同的親和性的任務棧(即taskAffinity,注意同一個應用程序中的Activity的親和性一樣),如果有,剛直接把這個棧整體移動到前台,並保持棧中的狀態不變,即棧中的Activity順序不變,如果沒有,則新建一個棧來存放被啟動的Activity

  1,前提:Activity A,B,C都在“FlagTest應用“中

  場景演示:Activity A啟動開辟Task堆棧,狀態為:A,接着Activity A啟動Activity B ,Activity B啟動Activity C,而Activity C設置了FLAG_ACTIVITY_NEW_TASK,默認同個應用中的taskAffinity相同,此時的Task堆棧狀態為:ABC.

  2,前提:Activity A在”FlagTest應用“中,Activity B,C在”FlagTest應用1“中

  場景演示:Activity A啟動開辟Task堆棧(TaskA狀態為:A),接着Activity A啟動Activity B,Activity B設置了FLAG_ACTIVITY_NEW_TASK,這時因為是不同的應用,其taskAffinity不同,則開辟了Task堆棧(TaskB狀態為:B),Activity B啟動了Activity C,此時TaskB狀態為:BC。當從Activity A重新啟動Activity B時,因為Activity B已經在TaskB中了,所以是將TaskB返回到前台,而且TaskB中的Activity順序不變,也就是此時顯示給用戶的是Activity C。

FLAG_ACTIVITY_NO_ANIMATION

  設置此標識的intent所啟動的Activity將沒有過渡動畫

FLAG_ACTIVITY_NO_HISTORY

  設置了此標識的intent所啟動的Activity將不會放入Task中

  場景演示:Activity A啟動開辟了TaskA,狀態:A,Activity A啟動了Activity B,Activity B設置了FLAG_ACTIVITY_NO_HISTORY,當Activity B啟動Activity C后,TaskA的狀態為AC,因為Activity B不會被放進Task中

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

  這個標識一般與FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET一起使用,詳細請見上面的 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET。

FLAG_ACTIVITY_SINGLE_TOP

  此標識為棧頂一個Activity只能有一個實例

  場景演示:Activity A啟動開辟了TaskA,在Activity A中啟動Activity B,而Activity B設置了FLAG_ACTIVITY_SINGLE_TOP標識,此時TaskA的狀態為:AB,那么當有intnet要請求Activity B時,則不會創建Activity B的實例,而是直接用原來棧中的Activity B,此時TaskA的狀態為:AB,如果是默認方式,那么將實例化一個Activity B,那么此時的TaskA狀態為:ABB.

 

  這部分Intent Flag是開發中比較常用的Flag,可以通過設定這些Flag達到簡易管理項目中的Activity,使其符合項目中Activity跳轉的邏輯,當然要進行對項目中全部Activity更有效的管理,還是應該自己實現類似Task的管理功能的。

二:LaunchMode 部分

  這部分在官方API guides有詳細的介紹http://developer.android.com/guide/topics/manifest/activity-element.html

  Activity的啟動模式有四種,"standard", "singleTop" ,"singleTask" ,"singleInstance", 默認的啟動模式是standard,這四種模式分為4中,standard,singleTop是一種,Activity能夠被實例化多次,這些實例可以屬於任何的棧,singleTask,singleInstance是另一中,他們只能開啟一個棧,並且總是存在於棧低。

使用情況 啟動模式 能否多次實例化? 注釋
大多數Activity啟動方式 standard 系統默認方式,總是創建一個instance
singleTop 有條件 當棧頂已有改Activity的實例,則不創建,其他的和standard一樣
特殊啟動(不推薦經常使用) singleTask 作為一個新棧的根Activity,只能實例化一次
singleInstance 與singleTask基本一樣,不同的是擁有singleInstance的Activity所在的棧只能存放這個Activity

三:Manifest中<activity>屬性

  這部分在官方的開發者文檔中有詳細的介紹http://developer.android.com/guide/topics/manifest/activity-element.html

  與Intent有關的部分屬性:1,taskAffinity;2,alwaysRetainTaskState; 3,clearTaskOnLaunch; 4,finishOnTaskLaunch

1,taskAffinity屬性: 

   (1) taskAffinity屬性應和FLAG_ACTIVITY_NEW_TASK標志及allowTaskReparenting屬性結合使用

   (2) 與FLAG_ACTIVITY_NEW_TASK標志結合:

       a. 前題: Activity A, B在同一個應用中, Activity A與Activity B設置不同的taskAffinity屬性.

          場景演示: Activity A啟動開僻Task堆棧,命名為TaskA(TaskA堆棧狀態: A), 在Activity A中啟動Activity B, 啟動Activity B

                   的Intent中設置FLAG_ACTIVITY_NEW_TASK標志,這時系統會新開僻一個Task堆棧,TaskB(TaskB堆棧狀態: B).

       b. 前題: Activity A在"FlagTest應用"中, Activity C在"FlagTest1應用"中, Activity A和ActivityC設置了相同的taskAffinity屬性.

          場景演示: Activity A啟動開僻Task堆棧,命名為TaskA(TaskA堆棧狀態: A), 在Activity A中啟動Activity C, 啟動Activity C的Intent中設置FLAG_ACTIVITY_NEW_TASK標志,這時Activity C會壓入與Activity A堆棧相同的TaskA堆棧(TaskA堆棧狀態: AC).

   (3) 與allowTaskReparenting屬性:

         場景演示: 在"FlagTest應用"中有Activity A, Activity A與"FlagTest應用"中的其它Activity有默認的關系(taskAffinity屬性都沒有設置), 並且allowTaskReparenting屬性設置為true, 現在存在一個"FlagTest1應用"啟動了"FlagTest應用"中的Activity A,  這時Activity A與"FlagTest1應用"中的Activity在同一個Task,命名這個Task堆棧為TaskA, 這時"FlagTest應用"啟動, 並且又打開Activity A, 這時Activity A會從TaskA堆棧中轉移到"FlagTest應用"所在的堆棧, 即Activity A可以在多個堆棧中來回轉移. 

2, alwaysRetainTaskState屬性:

    如果Task堆棧中的Root Activity設置了此屬性值為true, 不管出現任何情況, 一直會保留Task棧中Activity的狀態.

3, clearTaskOnLaunch屬性:    

    如果Task堆棧中的Root Activity設置了此屬性值為true, 只要你一離開這個Task棧, 則系統會馬上清理除了Root Activity的全部Activity.

4, finishOnTaskLaunch屬性:

    如果某Activity設置了finishOnTaskLaunch屬性, 只要你一離開這個Task棧, 則系統會馬上清除這個Activity,不管這個Activity在堆棧的任何位置.

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM