Android TaskAffinity和allowTaskReparenting属性

3,977 阅读3分钟

一、TaskAffinity

TaskAffinity翻译过来就是“任务相关性”,它表示了一个Activity所需要的任务栈的名字。 在平时的开发中,我们一般很少使用到TaskAffinity这个属性,也没有听说过Activity需要什么任务栈之类的。其实,在默认情况下,如果不指定TaskAffinity属性,Activity所需任务栈的名字就是应用的名字

1、默认的任务栈

我们在一个应用中启动三个Activity,然后在Terminal中执行adb shell dumpsys activity命令,结果如下:

Running activities (most recent first):
      TaskRecord{853dee #503 A=com.hwldzh.myapplication U=0 StackId=1 sz=3}
        Run #4: ActivityRecord{c1a608e u0 com.hwldzh.myapplication/.ThirdActivity t503}
        Run #3: ActivityRecord{7289178 u0 com.hwldzh.myapplication/.SecondActivity t503}
        Run #2: ActivityRecord{8539f65 u0 com.hwldzh.myapplication/.MainActivity t503}

可以看到,启动的三个Activity都位于“com.hwldzh.application”这个任务栈中,而这个名字就是我们这个应用的包名。

2、TaskAffinity初登场

接下来,我们给ThirdActivity加上TaskAffinity的属性,即在Manifest中的声明如下:

<activity 
      android:name=".ThirdActivity"
      android:taskAffinity="com.hwldzh.ThirdActivity"/>

我们继续执行在Terminal中执行adb shell dumpsys activity命令,看ThirdActivity是否处于“com.hwldzh.ThirdActivity”的任务栈中:

Running activities (most recent first):
      TaskRecord{853dee #503 A=com.hwldzh.myapplication U=0 StackId=1 sz=3}
        Run #4: ActivityRecord{c1a608e u0 com.hwldzh.myapplication/.ThirdActivity t503}
        Run #3: ActivityRecord{7289178 u0 com.hwldzh.myapplication/.SecondActivity t503}
        Run #2: ActivityRecord{8539f65 u0 com.hwldzh.myapplication/.MainActivity t503}

可以看到ThirdActivity依然运行在以包名为名字的任务栈中。这说明了在启动模式为Standard下,单独使用TaskAffinity属性是无效的

3、TaskAffinity和SingleTask配合

我们在ThirdActivity的Manifest声明中加上SingleTask启动模式:

<activity
      android:name=".ThirdActivity"
      android:launchMode="singleTask"
      android:taskAffinity="com.hwldzh.ThirdActivity"/>

然后执行adb shell dumpsys activity命令,得到如下结果:

Running activities (most recent first):
      TaskRecord{5da8e4c #25630 A=com.hwldzh.ThirdActivity U=0 StackId=1 sz=1}
        Run #7: ActivityRecord{1111a92 u0 com.hwldzh.myapplication/.ThirdActivity t25630}
      TaskRecord{b00bc91 #25629 A=com.hwldzh.myapplication U=0 StackId=1 sz=2}
        Run #6: ActivityRecord{93040cf u0 com.hwldzh.myapplication/.SecondActivity t25629}
        Run #5: ActivityRecord{464be1f u0 com.hwldzh.myapplication/.MainActivity t25629}

在将ThirdActivity的启动模式改为SingleTask之后,可以看到ThirdActivity启动的时候创建了一个新的任务栈,并且该任务栈的名字为TaskAffinity属性设置的“com.hwldzh.ThirdActivity”。

所以,当TaskAffinity和SingleTask启动模式配对使用时,它是具有该模式的Activity的目前任务栈的名字,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中。

二、allowTaskReparenting

allowTaskReparenting属性的作用是Activity的迁移。当allowTaskReparenting属性和TaskAffinity配合使用时,Activity可以从一个任务栈迁移到另一个任务栈。

迁移的规则是:从一个与该Activity TaskAffinity属性不同的任务栈中迁移到与它TaskAffinity相同的任务栈中。

举个例子:当一个应用A启动了应用B的某个Activity后,如果这个Activity的allowTaskReparenting属性设置为true,那么当应用B被启动,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。 具体点来说,现在有两个应用A和B,A启动了B的一个Activity C,然后按Home键回到桌面,然后再单击B的桌面图标,这个时候不是启动了B的主Activity,而是重新显示了已经被应用A启动的Activity C。我们也可以理解为,C从A的任务栈转移到了B的任务栈中。 可以这么理解,由于A启动了C,这个时候C只能运行在A的任务栈中,但是C属于B应用,正常情况下,它的TaskAffinity值肯定不可能和A的任务栈相同,所以当B启动后,B会创建自己的任务栈,这个时候系统发现C原本想要的任务栈已经创建了,所以就把C从A的任务栈中转移过来了。

参考书目

1、《Android开发艺术探索》