Android中singleInstance和taskAffinity的優先級

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。


Source


References

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章