android:allowTaskReparenting
在App A中,我們有根ActivityRootA
和另外一個ActivityReparentableA
<application
android:label="@string/app_name">
<activity android:name=".RootA">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name=".ReparentableA"
android:allowTaskReparenting="true"/>
</application>
App A的包名是com.app.a
,所以默認的taskAffinity
就是com.app.a
在App B中,我們有根ActivityRootB
<application
android:label="@string/app_name">
<activity android:name="RootB">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
現在我們從桌面打開App B。這會開啓新的Task,並在Task中創建新的Activity實例RootB
作爲根Activity。從RootB
Activity中使用標準Intent啓動ReparentableA
,沒有指定任何Flags。ReparentableA
的一個實例將會被創建並放置到RootB的頂部。
點擊Home
鍵
現在我們從桌面啓動App A,這次啓動將會創建一個新的Task和新的Activity(RootA
)實例。RootA
作爲根Activity。
注:當Android啓動一個lacuncher
Intent,它將會自動設置flagsIntent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
。因爲這個原因,Root
的啓動將會觸發
ATask Reparenting
。此時,Android查找所有其他的Task,如果有Activity擁有與當前Task相同affinity
屬性,並且android:allowTaskReparenting="true"
,它會發現ReparentableA
在App B的Task中,然後移動ReparentableA
到App A的Task底部(這裏是在RootA
的頂部
)。所以我們將會看到ReparentableA
。如果我們回到App B中,我們會發現,ReparentableA
消失了,僅剩下RootB
注意
Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
使用Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
來清除一個Task,僅僅工作在已經存在一個目標Activity的實例在Task的底部(root),如果Task底部的Activity已經被清除,你將不能通過啓動底部的Activity來清除Task.Android僅僅會創建一個新的目標實例在Task的頂部,這可能不是你想要的。Intent.FLAG_ACTIVITY_CLEAR_TASK
和Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
的不同
正如前面提到的,CLEAR_TOP | SINGLE_TOP
僅僅工作在已經有一個目標Activity實例存在Task。CLEAR_TASK
會清除掉所有在Task中的activity,並重新創建一個新的實例,而不管要啓動的activity是否已經存在在Task中。最終,目標activity必定存在於Task的底部。Intent.FLAG_ACTIVITY_CLEAR_TASK
和Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
的不同
CLEAR_TASK
總是會清除Task,而RESET_TASK_IF_NEEDED
只會在下面情況下,清除Task
- 創建新的Task(在這種情況下,設置了
taskreparent
屬性爲true的Activity將會被置於新Task的頂部 - 如果android將後臺Task轉換爲前臺Task(在這種情況下,這個Task僅僅清除以
Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
啓動的Activity,以及任何在這些Activity之上的Activity。)注:底部的Activity永遠不會被清除,在這種情況下。
- 創建新的Task(在這種情況下,設置了
singleTask
與FLAG_ACTIVITY_NEW_TASK
區別
singleTask
啓動的Activity,系統會先判斷對應的標識爲taskAffinity
的Task是否存在,如果存在則查看該Task中是否有該Activity實例,如果有,則將該activity上的所有其他的activity清除,使得啓動的activity在Task頂部。如果沒有該Activity實例,就創建一個。總之就是保證在對應的Task中唯一。singleInstance
全局唯一
FLAG_ACTIVITY_NEW_TASK
與taskAffinity
一起使用。保證在對應的taskAffinity
Task中唯一,如果已經存在則什麼都不做(搭配FLAG_ACTIVITY_CLEAR_TOP
可以清除該activity之上的其他activity),如果不存在則創建該Activity