taskAffinity属性

  我们在AndroidManifest.xml文件中可以指定taskAffinity属性,如下所示。

1
2
3
4
<activity
android:name=".CActivity"
android:launchMode="singleTask"
android:taskAffinity="com.yanfangxiong.taskAffinity" />

  它表示任务相关性,实际上的作用是指定所在的任务栈的名称,指定taskAffinity也需要注意以下几点

  1. taskAffinity的值不要和包名一样,因为默认情况下,Activity都是运行在包名的任务栈中;
  2. taskAffinity的值中必须要有”.”,不然无法运行。

  像上面的代码,当启动CActivity的时候,会看是否有com.yanfangxiong.taskAffinity的任务栈存在,如果没有则会新建名为com.yanfangxiong.taskAffinity的任务栈,然后再将CActivity放入到任务栈,如果有该任务栈存在,则会看是否有CActivity的实例,如果有则调用onNewIntent()方法。
但但但是,一般我们使用taskAffinity没有作用,为什么呢?因为taskAffinity属性要和singleTask启动模式(Intent的FLAG_ACTIVITY_NEW_TASK)一起使用,或者和allowTaskReparenting属性一起使用

和singleTask一起使用

  我们可以像上面一样在manifest文件中指定launchMode为singleTask,然后给Activity指定taskAffinity属性。

1
2
3
4
5
6
7
8
9
10
11
12
<activity
android:name=".AActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".BActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:taskAffinity="com.yanfangxiong.taskAffinity" />

  或者我们不置顶BActivity的launchMode,通过Intent的flag,如下。

1
2
3
4
5
6
val intent = Intent(this@AActivity, BActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val queryIntent = this@AActivity.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
if (queryIntent != null && queryIntent.isNotEmpty()) {
this@AActivity.startActivity(intent)
}

  上面的代码表示AActivity将会运行在名字为包名的任务栈,而BActivity将会运行在名字为com.yanfangxiong.taskAffinity的任务栈中。我们通过如下代码打印出taskId,看看两者是否是相同的。

1
2
3
4
override fun onResume() {
super.onResume()
Log.d("fxYan", "$taskId")
}

  然后我们运行程序,之后从AActivity跳转到BActivity,看看两者是否在同一个任务栈中。001
可以看到两者在两个不同的任务栈中。

和allowTaskReparenting一起使用

  栗子已备好,大人请品尝。我创建了两个app,一个是com.yanfangxiong.test,记为A应用,另外一个是com.yanfangxiong.test2,记为B应用。A应用中有一个AActivity,B应用中有一个AActivity和一个BActivity;然后从A应用的AActivity点击后会打开B应用的BActivity。
然后我们分别修改BActivity的allowTaskReparenting属性,执行相同的流程。

  1. 打开A应用;
  2. 通过A应用的AActivity启动B应用的BActivity;
  3. 回到桌面;
  4. 通过B应用的launcher启动B应用。

  这里涉及到一个命令,可以查看activity的信息。

1
$ adb shell dumpsys activity activities

allowTaskReparenting为false

  我们先来看看当B应用的BActivity的allowTaskReparenting为false的情况。为了简化,我这里只输出第四步的activity信息,如下所示。
  先来看看B应用的任务栈信息,可以看到,只有我们启动的AActivity在任务栈中。
002
  然后再看看A应用的任务栈信息,可以看到,有B应用的BActivity和A应用的AActivity在任务栈中。
003

allowTaskReparenting为true

  然后我们看看allowTaskReparenting为true的情况,如下所示。
  先来看看B应用的任务栈信息,可以看到神奇的一幕,有我们启动的AActivity以及之前通过A应用启动的BActivity在任务栈中,而且这个时候返回的时候是返回AActivity。
004
  然后再看看A应用的任务栈信息,可以看到,只有A应用的AActivity在任务栈中。
005

  allowTaskReparenting属性为true的时候,BActivity发现B应用启动后,有自己想要的任务栈,所以会从A应用的任务栈迁移到B应用的任务栈,就出现了上面神奇的一幕。

本文标题:taskAffinity属性

文章作者:严方雄

发布时间:2018-09-12

最后更新:2018-09-13

原始链接:http://yanfangxiong.com/2018/09/12/taskAffinity属性/

0%