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在堆棧的任何位置.