我们首先要有task这个概念,我们可以把task看作存放运行时Activity的集合,也就是一个存放我们App中Activity任务栈 系统按照启动的顺序把Activity有序的存放在里面。
而 taskAffinity叫做归属,可以把它理解成把Activity分组的意思,它会把具有相同的Activity“吸附”进一个新的任务栈,可能有人跟我一样没了解这个属性根本看不到有哪里使用过它,其实每个Activity都有默认的taskAffinity属性,我们可以在manifest的<application/>统一设置taskAffinity,也可以在单个<activity/>单独指定。
那它有什么用呢?我们可以通过一个例子来演示一下.
我们先创建Demo1工程,其中包含Activity1,和Activity2,我们指定Activity2的taskAffinity为“com.yang.test1”:
<activity android:name=".Activity1">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Activity2"
android:taskAffinity="com.yang.test1" />
其中Activity1的代码:
public class Activity1 extends Activity {
TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.act_tv);
textView.setText("Activity1");
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Activity1.this, Activity2.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//先留意下这个flag
startActivity(intent);
}
});
}
}
然后我们在创建Demo2,也有Activity3,和Activity4:
<!--taskAffinity和Demo1中的名字相同-->
<activity android:name=".Activity3"
android:taskAffinity="com.yang.test1">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Activity4"
android:taskAffinity="com.yang.test1" />
Activity3中的代码:
public class Activity3 extends Activity {
TextView textView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.act_tv);
textView.setText("Activity3");
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Activity3.this, Activity4.class);
startActivity(intent);
}
});
}
}
Activity2和Activity4的代码就不贴了,显示时能区分就行了。
好了,写了这么多无聊的代码,我们就开始演示了,我们先启动Demo2默认进入Activity3,然后通过点击事件进入Activity4,这时我们把Demo2退到后台,接着我们启动Demo1的Activity1,然后点击跳转Activity2。
到这里你可能觉得和平时没什么不一样,但当我们点击返回键时,你会发现原本返回顺序是:Activity2->Activity1,变成了Activity2->Activity4->Activity3->Activity1,是不是有点奇怪?
其实是因为我们两个Demo中Activity设置了相同的taskAffinity,当以FLAG_NEW_TASK启动Activity时,系统会在已启动的Activity寻找跟它相同的taskAffinity,如果有则把这些Activity压进前台Task,并把自己压进Task的顶端并显示,没有则新建Task并把自己进栈。
上述Demo2中Activity1跳转Activity2时,系统则寻找跟它相同的taskAffinity,这时候系统发现Activity3和Activity4是同个taskAffinity并已启动,则把这两个Activity先加进Demo2的Task,最后才把Activity2加进Task。
这里可以举一个实际中的例子,相信大家都做过推送,当用户点击通知栏消息时我们需要在Intent中加FLAG_NEW_TASK跳转具体的推送界面,如果App已经启动过,当你点返回键时你会发现之前启动过的界面会显示出来,
也就是说系统把相同taskAffinity的Activity的Task移到前台。前面我们已经提到Activity默认是设置了taskAffinity,所以如果不作修改,Activity的taskAffinity都是一样的,所以当我们点击推送时跳转的不只是推送界面,也包含了已经启动的Activity集合。
我们可以总结下:
1.每个Activity都有默认的taskAffinity属性
2.taskAffinity是指定Activity所属栈的,默认如果不设置的话App默认只有一个栈。
3.如果跳转界面时intent加了FLAG_NEW_TASK,系统会把已启动并且具有相同taskAffinity属性的Activity移至前台,也就是说 可能会新开一个栈并把不同App中相同taskAffinity属性Activity"吸附"进栈。