相關的基本概念:
一、任務棧(Task)html
若干個Activity的集合的棧表示一個Task。
棧不只僅只包含自身程序的Activity,它也能夠跨應用包含其餘應用的Activity,這樣有利於保障用戶體驗,維護用戶操做體驗上的完整性。
例如:微信ActivityA 分享文章到QQActivityB,兩個activity是存在於不一樣app中的,可是被系統放在一個任務中,分享後,用戶按back鍵返回,能夠返回到原來的微信Activity A中,這就確保了用戶體驗。
二、查看當前系統的任務棧
命令行中 --> adb shell dumpsys activity
三、Activity 的相關屬性
android:taskAffinity:是否認義了該屬性,對接下來討論到的singleTask影響甚大,若是設置了Activity的taskAffinity屬性值,Activity將在TaskName爲指定值的獨立Task中啓動,不然,將在原來的默認Task中。
android:allowTaskReparenting:主要做用是activity的遷移,程序A已經啓動了若干個Activity,其中包含Activity1(這個Activity1擁有該屬性),當程序B也要啓動它的時候,其可遷移到程序B內。
android:alwaysRetainTaskState:操做系統會在程序長時間不會動的時候,清除Task狀態,若是開啓這個,系統會繼續保持直到再次打開,只對根Activity生效(ABC,A是棧底,C是棧頂,只能對A便可)。例如微信在後臺,當咱們再次打開應用時,系統會判斷是否已經存在以A爲根Activity的棧,若是有,直接使用該棧,並顯示棧頂的Activity。
android:clearTaskOnLaunch:用來標記是否在啓動該Activity時,清除除根目錄的其餘Activity
android:exported:是否支持其它應用調用當前組件。默認值:包含有intent-filter 默認值爲true(); 沒有intent-filter默認值爲false。
四種啓動模式:
standard:每次激活Activity時(startActivity),都建立Activity實例,並放入任務棧;
singleTop:若是該Activity位於任務棧棧頂,則不須要建立,複用實例而且會調用該實例的onNewIntent()方法將Intent對象傳遞到這個實例中,其他狀況都要建立Activity實例;(singleTop模式,只在當前任務棧中生效、startActivityForResult啓動一個設置了singleTop的activity,singleTop模式將無效)
關於onNewIntent():
根據文檔知,當Activity的啓動模式是singleTop或者使用FLAG_ACTIVITY_SINGLE_TOP這個標記啓動新的Activity而且Activity棧頂就是待啓動的Activity的時候,會調用原Activity的這個方法;例子:QActivity爲棧頂複用模式,當Qactivity位於棧頂時,再次打開,onResume() -->onPause() -->onNewIntent() -->onResume() 。當Qactivity不位於棧頂時,onNewIntent-->onRestart-->onStart-->onResume(也就是說只要棧頂不是Qactivity ,都會建立新的實例,是Qactivity則重用不新建)。
singleTask:使用好棧內複用模式對taskAffinity屬性的理解很重要。
存在相同taskAffinity屬性值的Task:不存在實例,則新建Activity實例。若是存在則把當前實例中複用實例, 這個 Activity 啓動而且清除頂部的 Acitivity ,經過標識 CLEAR_TOP。
taskAffinity屬性值不同的Task:在這個 Task 中新建這個 Activity 實例。
singleInstance:和singleTask差很少,惟一不一樣的是singleInstance Activity實例的Task只能存放一個該模式的Activity實例,例如Qactivity加載Wactivity都會被放入其它的Task中,若是存在與Wactivity相同affinity的Task,則在該Task內建立Wactivity。若是不存在,則從新生成新的Task併入棧。
經常使用Intent Flags:
FLAG_ACTIVITY_NEW_TASK: 若是task中已經有了你要啓動的activity的話,當前task會被帶到前臺(無論這個activity是否在前臺,有可能activity上邊還壓有別的activity)。若是配合FLAG_ACTIVITY_NEW_MULTI_TASK,則不管什麼狀況都會建立新的Task,就成了相似 singleInstance 的狀況了。若是配合 FLAG_ACTIVITY_CLEAR_TASK,則會先清空該棧,而後向棧中添加目標Activity,棧ID不變。
例如:Flag爲FLAG_ACTIVITY_NEW_TASK,Qactivity(棧爲LOL)啓動Wactivity(棧爲DOTA),接着啓動Eactivity(棧爲DOTA),Home回桌面。打開該應用,Qactivity啓動Wactivity,Eactvity會出如今前臺,由於它是整塊棧啓動(裏面順序不變)。
FLAG_ACTIVITY_SINGLE_TOP: 至關於launchMode中的singleTop。
FLAG_ACTIVITY_CLEAR_TOP: 與singleTask相似,但有極大區別,它會銷燬目標Activity和它之上的全部Activity,從新建立目標Activity,並無執行onNewIntent()。
tips:
指定啓動模式時,Flags的優先級大於launchMode,當二者都有時,以
Intent Flag有效。
注意事項:
一、
當目標的啓動模式不爲標準模式時,不要使用startActivityForResult去啓動目標,容易出現你意想不到的結果。
例如:(大概意思,startActivityForResult至關於白設置,會返回一個取消的結果)
**if the activity you
* are launching uses the singleTask launch mode, it will not run in your
* task and thus you will immediately receive a cancel result
二、當Activity執行了onDestroy,沒有執行finish,那麼實例都仍是存在棧裏的。但Activity被finish掉了,則它會是新建實例從新入棧,不會按啓動模式想的那樣。
轉載註明來自:http://www.cnblogs.com/wujiancheng/