Abstract
我們知道,singleInstance會讓新建的activity實例放進新的task棧中,而taskAffinity又可以通過指定task棧來實現將activity實例放入指定task棧中,本文主要通過四個實例,對singleInstance和taskAffinity進行交叉對比,說明singleInstance和taskAffinity的優先級。
對比流程爲,創建兩個Activity分別名爲MainActivity和SingleInstanceActivity,由MainActivity點擊按鈕啓動SingleInstanceActivity,二者均在onCreate中打印日誌。
爲了便於讀者閱讀,代碼、日誌及終端結果均刪掉了無關信息。
Case 1
- LaunchMode: singleTask
- taskAffinity: same
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="singleinstancedemo.zengyu.com.singleinstancedemo">
<application
android:name=".DemoApplication">
<activity
android:name=".MainActivity"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo">
</activity>
<activity
android:name=".SingleInstanceActivity"
android:launchMode="singleTask"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo" />
</application>
</manifest>
Logcat
E/DemoApplication: process id = 21205
E/MainActivity: process id = 21205, task id = 1686
E/SingleInstanceActivity: process id = 21205, task id = 1686
Terminal
$ adb shell dumpsys activity | grep singleinstancedemo.zengyu.com.singleinstancedemo | grep Record
TaskRecord{8b7c011 #1686 A=singleinstancedemo U=0 StackId=1 sz=2}
Run #1: ActivityRecord{da0ab3e u0 singleinstancedemo.zengyu.com.singleinstancedemo/.SingleInstanceActivity t1686}
Run #0: ActivityRecord{b2119 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.MainActivity t1686}
Result
由於我們的task棧中沒有SingleInstanceActivity的實例,因此此時launchMode不管是standard,singleTop還是singleTask,相對於singleInstance是沒有區別的,都不會主動去創建一個新的task棧。
taskAffinity的缺省值是包名,所以此處註冊清單中我們設置了兩個相同值,和都不設置(缺省)的情況下,是一樣的效果。
從日誌和終端結果看出,非singleInstance且taskAffinity相同(缺省)的情況下,新建的activity實例是位於同一個task棧中。
Case 2
- LaunchMode: singleTask
- taskAffinity: different
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="singleinstancedemo.zengyu.com.singleinstancedemo">
<application
android:name=".DemoApplication">
<activity
android:name=".MainActivity"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo">
</activity>
<activity
android:name=".SingleInstanceActivity"
android:launchMode="singleTask"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo2" />
</application>
</manifest>
Logcat
E/DemoApplication: process id = 21631
E/MainActivity: process id = 21631, task id = 1690
E/SingleInstanceActivity: process id = 21631, task id = 1691
Terminal
$ adb shell dumpsys activity | grep singleinstancedemo.zengyu.com.singleinstancedemo | grep Record
TaskRecord{607a8af #1691 A=singleinstancedemo.zengyu.com.singleinstancedemo2 U=0 StackId=1 sz=1}
Run #1: ActivityRecord{7d07683 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.SingleInstanceActivity t1691}
TaskRecord{d0254bc #1690 A=singleinstancedemo.zengyu.com.singleinstancedemo U=0 StackId=1 sz=1}
Run #0: ActivityRecord{843c1a0 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.MainActivity t1690}
Result
由於taskAffinity不同,因此新建的activity實例被放入了指定名稱的task棧中。
Case 3
- LaunchMode: singleInstance
- taskAffinity: same
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="singleinstancedemo.zengyu.com.singleinstancedemo">
<application
android:name=".DemoApplication">
<activity
android:name=".MainActivity"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo">
</activity>
<activity
android:name=".SingleInstanceActivity"
android:launchMode="singleInstance"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo" />
</application>
</manifest>
Logcat
E/DemoApplication: process id = 22358
E/MainActivity: process id = 22358, task id = 1698
E/SingleInstanceActivity: process id = 22358, task id = 1698
Terminal
$ adb shell dumpsys activity | grep singleinstancedemo.zengyu.com.singleinstancedemo | grep Record
TaskRecord{6107ebf #1699 A=singleinstancedemo.zengyu.com.singleinstancedemo U=0 StackId=1 sz=1}
Run #1: ActivityRecord{3293570 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.SingleInstanceActivity t1699}
TaskRecord{10508ea #1698 A=singleinstancedemo.zengyu.com.singleinstancedemo U=0 StackId=1 sz=1}
Run #0: ActivityRecord{b34da09 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.MainActivity t1698}
Result
在taskAffinity指定了相同的task棧前提下,singleInstance仍然將新建的activity實例放入了新的task棧中,因此可以得出singleInstance的優先級大於taskAffinity。
Case 4
- LaunchMode: singleInstance
- taskAffinity: different
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="singleinstancedemo.zengyu.com.singleinstancedemo">
<application
android:name=".DemoApplication">
<activity
android:name=".MainActivity"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo">
</activity>
<activity
android:name=".SingleInstanceActivity"
android:launchMode="singleInstance"
android:taskAffinity="singleinstancedemo.zengyu.com.singleinstancedemo2" />
</application>
</manifest>
Logcat
E/DemoApplication: process id = 22541
E/MainActivity: process id = 22541, task id = 1702
E/SingleInstanceActivity: process id = 22541, task id = 1703
Terminal
$ adb shell dumpsys activity | grep singleinstancedemo.zengyu.com.singleinstancedemo | grep Record
TaskRecord{2ae4244 #1703 A=singleinstancedemo.zengyu.com.singleinstancedemo2 U=0 StackId=1 sz=1}
Run #1: ActivityRecord{9f03f08 u0 singleinstancedemo.zengyu.com.singleinstancedemo/.SingleInstanceActivity t1703}
TaskRecord{fb1f2d #1702 A=singleinstancedemo.zengyu.com.singleinstancedemo U=0 StackId=1 sz=1}
Run #0: ActivityRecord{603c9ff u0 singleinstancedemo.zengyu.com.singleinstancedemo/.MainActivity t1702}
Result
在既設置singleInstance,taskAffinity又不同的情況下,二者都是在新的task棧,理所當然新建的activity實例被放進了新的task棧中。
Conclusion
即使taskAffinity相同,當LaunchMode爲singleInstance時,仍然會在新的task中創建activity實例。因此singleInstance的優先級大於taskAffinity。