Test 1:
为了进行对比,先将SingleTaskActivity的属性设置为默认模式,并且不设置标签android:taskAffinity:
<activity
android:name=".SingleTaskActivity">
<!--android:taskAffinity="com.zj.task">
android:launchMode="singleTask"-->
<intent-filter >
<action android:name="com.zj.test.launch_singletask"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("com.zj.test.launch_singletask");
Bundle bundle = new Bundle();
bundle.putString("mainact", "1_Button1");
intent.putExtras(bundle);
startActivity(intent);
}
});
findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent("com.zj.test.launch_singletask");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundle = new Bundle();
bundle.putString("mainact", "1_Button2");
intent.putExtras(bundle);
startActivity(intent);
}
});
Log输出位置:
App A MainActivity:
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.d("SingleTask", "App A's MainActivity " +"所在的任务的id为: " + getTaskId());
}
App A SingleTaskActivity:
<strong> </strong>@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.d("SingleTask", "App A's SingleTaskActivity " +"所在的任务的id为: " + getTaskId());
}
App B MainActivity:
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.d("SingleTask", "App B's MainActivity " +"所在的任务的id为: " + getTaskId());
}
测试步骤为:
测试结果:
在App A 中两种启动方式中,SingleTaskActivity都和启动它的MainActivity位于同一个Task,也就是说FLAG_ACTIVITY_NEW_TASK根本没有发挥作用,
在App B 中两种启动方式中,当不设置FLAG_ACTIVITY_NEW_TASK时,SingleTaskActivity和启动它的MainActivity位于同一个Task,设置了以后,复用了已经存在位于App A中的SingleTaskActivity。
Test 2:
下面把SingleTaskActivity标签android:taskAffinity设置上内容 ,launchMode保持不变
,如下(注意 app A 和 app B的包名不能和android:taskAffinity一样,否则起不到测试效果)
<activity
android:name=".SingleTaskActivity"
android:taskAffinity="com.zj.task">
<!--android:launchMode="singleTask"-->
<intent-filter >
<action android:name="com.zj.test.launch_singletask"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
测试结果:
在两个app下FLAG_ACTIVITY_NEW_TASK都起作用(对于app B而言,新建的时候发现目标Task的栈顶已经有一个实例,所以没有新建)。
先App A,再App B(home之前回退SingleTaskActivity):
在两个app下FLAG_ACTIVITY_NEW_TASK都起作用,且新建了Task。
standard和singleTop(可以被实例化多次), 结论如下:
启动者和被启动者在同一app下(声明在同一个AndroidManif.xml文件里),必须同时使用FLAG_ACTIVITY_NEW_TASK和标签android:taskAffinity才能在新的Task中启动,缺少其中的一个都会和启动者位于同一个Task。
FLAG_ACTIVITY_NEW_TASK,则二者位于同一个Task内。如果使用的话,会新建Task,所新建的位置依据标签android:taskAffinity而定(1.如果不指定则在被启动者所在App的Task内新建,当然前提是这个被启动者所在的App的Task已经存在,2.如果目标Task内的栈顶已经有一个实例,这时候实际上不新建的,相当于要新建的内容已经存在了)。
以上是一个对比测试,下面转入本文主题,对singleTask模式的测试,
Test 3::
首先依然不设置标签android:taskAffinity,启动模式为singleTask:
<activity
android:name=".SingleTaskActivity"
android:launchMode="singleTask">
<!--android:taskAffinity="com.zj.task"> -->
<intent-filter >
<action android:name="com.zj.test.launch_singletask"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
测试结果:
先App A,再App B (不管是否回退都一样)
在App A 中两种启动方式,SingleTaskActivity都和启动它的MainActivity位于同一个Task,也就是说FLAG_ACTIVITY_NEW_TASK根本没有发挥作用,而且singleTask也没有启动新Task。
在App B 中两种启动方式:不管是否设置FLAG_ACTIVITY_NEW_TASK时,SingleTaskActivity和启动它的MainActivity都不位于同一个Task中(如存在,直接调用,如不存在,则在所属app的Task中新建出来)。
先App B,再App A:
App B的两种方式都会新建一个Task任务来启动SingleTaskActivity,如不回退,启动App A时则直接进入到App B启动好的SingleTaskActivity
Test 4:
下面把SingleTaskActivity标签android:taskAffinity设置上内容
<activity
android:name=".SingleTaskActivity"
android:launchMode="singleTask"
android:taskAffinity="com.zj.task" >
<intent-filter >
<action android:name="com.zj.test.launch_singletask"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
先App A,再App B:
先App B,再App A:
不管启动者和被启动着是否在同一app下,都会新建一个任务来启动SingleTaskActivity,且如果已经存在一个实例的话,就不会再次新建了。
结论:对于singleTask启动方式而言,
1.如果启动者和被启动者属于不同app的话,则只要系统中不存在这个类的实例,都会为SingleTaskActivity新建Task来启动它,存在的话就直接调用已存在的这个实例。
2.如果启动者和被启动者属于同一个app,需要设置标签android:taskAffinity以后,才会新建Task来启动,否则直接调用者所在Task内启动。
总结一下,singleTask启动方式Activity在系统中只会存在一份实例,启动时是否启动新Task,取决两个因素:启动者和被启动者的位置关系 和 标签android:taskAffinity的值。
初次发博说明代码实验,有些混乱,敬请见谅。