測試環(huán)境:Google Nexus 4- 5.0.0- API 21
工具: 使用adb shell dumpsys activity 查看activity 屬于哪個(gè)task

新建或重用activity的生命周期
啟動(dòng)一個(gè)Activity根據(jù)launchMode 和Intent flag判斷是新建還是重用:
新建 : onCreate -> onStart -> onResume; 重用: onNewIntent ->(onStart)-> onResume.
getIntent() 得到的是原來的intent, 可以通過setIntent(Intent) 更新intent
launchMode
Standard
默認(rèn)模式,新建并放在調(diào)用者的task里面
SingleTop
task頂一致則重用,否則新建
SingleInstance
該activity 只允許單例存在且獨(dú)占一個(gè)task 里面
SingleTask
-如果已存在taskAffinity 一致的task,進(jìn)一步判斷是否存在改activity,存在則重用,并把這位置之上的清除,否則新建一個(gè)放在上面。
-如果不存在taskAffinity 一致的task,新建一個(gè)task
taskAffinity: task類型,用于區(qū)分task. task的taskAffinity等于第一個(gè)插入該task的activity的taskAffinity,后面插入的activity的taskAffinity可以和stack的taskAffinity不同.
示例:
1.(A -> B -> C )
<Activity android:name=".A"/>
<Activity android:name=".B" android:launchMode="singleTask"/>
<Activity android:name=".C"/>
結(jié)果:
| task1 | task2 |
|---|---|
| A B C |
B默認(rèn)taskAffinity與A相同都是包名,所以放在相同task里面;并且還未存在 所以新建B
2.(A -> B -> C)
<Activity android:name=".A"/>
<Activity android:name=".B" android:launchMode="singleTask" android:taskAffinity=".task2"/>
<Activity android:name=".C"/>
結(jié)果:
| task1 | task2 |
|---|---|
| A | B C |
B定義了一個(gè)新taskAffinity,所以放在一個(gè)新task里面,C是默認(rèn)的,跟著創(chuàng)建它的B
3.(A -> B -> C -> B)
<Activity android:name=".A"/>
<Activity android:name=".B" android:launchMode="singleTask" android:taskAffinity=".task2"/>
<Activity android:name=".C"/>
結(jié)果:
| task1 | task2 |
|---|---|
| A | B |
前面步驟和上面一樣,最后轉(zhuǎn)到B需要清空B之上的activity
注意:
不同的taskAffinity 在長按home恢復(fù)的時(shí)候是分開顯示的,如果從用戶的角度來看,一個(gè) .apk 文件包含多個(gè)“應(yīng)用”,需要使用 taskAffinity 屬性將不同關(guān)聯(lián)分配給與每個(gè)“應(yīng)用”相關(guān)的 Activity。

taskAffinity 在兩種情況下生效:
- FLAG_ACTIVITY_NEW_TASK
singleTask,SingleInstance 也相當(dāng)于包含了這個(gè)flag
- android:allowTaskReparenting="true"
Activity 可以從其啟動(dòng)的任務(wù)移動(dòng)到與其具有關(guān)聯(lián)的任務(wù)(如果該任務(wù)出現(xiàn)在前臺)
示例:
應(yīng)用A啟動(dòng)應(yīng)用B的Activity B( 設(shè)置allowTaskReparenting="true"),按home鍵退回桌面啟動(dòng)應(yīng)用B,此時(shí)顯示的并不會是B的MainActivity,而是顯示Activity B
使用android:taskAffinity這個(gè)屬性時(shí),如果指定的值不含.,會出現(xiàn)這樣的錯(cuò)誤:
Failure [INSTALL_PARSE_FAILED_MANIFEST_MALFORMED]
可以考慮采用類似java包名的做法:比如com.xxx.xx
Intent Flag:
FLAG_ACTIVITY_SINGLE_TOP
與 "singleTop" launchMode 值相同的行為。FLAG_ACTIVITY_CLEAR_TOP
存在則重用并銷毀該位置之上的 Activity.
注:如果指定 Activity 的啟動(dòng)模式為 "standard",則該 Activity 也會從堆棧中刪除,并在其位置啟動(dòng)一個(gè)新實(shí)例FLAG_ACTIVITY_NEW_TASK
根據(jù)Affinity判斷是否需要?jiǎng)?chuàng)建新的Task,然后再創(chuàng)建新的Activity實(shí)例放進(jìn)去。(棧頂級別的重利用)FLAG_ACTIVITY_NO_HISTORY
如果設(shè)置,新的Activity將不再歷史stack中保留。用戶一離開它,這個(gè)Activity就關(guān)閉了。這也可以通過XML設(shè)置noHistory
注意: FLAG_ACTIVITY_NEW_TASK+FLAG_ACTIVITY_CLEAR_TOP 才等于singleTask.
清理返回棧
默認(rèn):如果用戶長時(shí)間離開任務(wù),則系統(tǒng)會清除所有 Activity 的任務(wù),根任務(wù)除外。 當(dāng)用戶再次返回到任務(wù)時(shí),僅恢復(fù)根 Activity。
可以使用下列幾個(gè) Activity 屬性修改此行為:
alwaysRetainTaskState
如果task根 Activity 中將此屬性設(shè)置為 "true",即使在很長一段時(shí)間后,所有 Activity 保留在其堆棧中。clearTaskOnLaunch
如果在task根 Activity 中將此屬性設(shè)置為 "true",則每當(dāng)用戶離開task然后返回時(shí),系統(tǒng)都會將堆棧清除到只剩下根 Activity。finishOnTaskLaunch
類似于 clearTaskOnLaunch,但它對單個(gè) Activity 起作用,而非整個(gè)任務(wù)。
startActivityForResult
Activity A startActivityForResult -> Activity B
在 Android 4.X 系統(tǒng)上,如果A 為singleTask,SingleInstance或者B為singleTask,SingleInstance則會在LaunchFlags中加入FLAG_ACTIVITY_NEW_TASK標(biāo)志,而含有FLAG_ACTIVITY_NEW_TASK標(biāo)志的話,onActivityResult將會立即接收到一個(gè)cancel的結(jié)果(android 5.0+ 可以正常返回了)
參考:
https://developer.android.com/guide/components/tasks-and-back-stack.html
http://www.cnblogs.com/lwbqqyumidi/p/3775479.html
http://m.itdecent.cn/p/eceda0e4963e