Activity启动模式需注意的坑
标准启动Standard模式版本差异:
-
在Lollipop之前,每次以MULTIPLE启动的Activity都会被压入当前任务的顶部,启动 N 次,在当前任务就会出现 N 个Activity的实例,每次Back键就会销毁一个,直到按了 N 次Back键。
-
从Lollipop开始,如果要以MULTIPLE启动Activity都是来自同一应用,那么还是会像之前一样,压入当前任务的顶部; 如果是来自不同应用,那么将会创建一个新的任务存放不同应用的activity,然后将Activity的实例压入新的任务中。Lollipop做的优化主要是针对多任务的显示。
SingleTask的两种情况:
- 待启动的Activity实例存在;
- 待启动的Activity实例不存在。
考虑第一种实例存在:如果某个任务中存在Activity实例,则仅仅是调用已有实例的onNewIntent()方法,在这之前,如果已有Activity实例不是位于任务顶,那么在它之上的其他Activity都会被销毁,确保目标Activity位于栈顶。
考虑第二种实例不存在:
启动Activity的实例不存在,这时候肯定会新建一个Activity的实例,但是否会新建一个任务呢?这又得分情况讨论,关键在于 taskAffinity这个属性。
新建的Activity实例需要寻找一个宿主任务,当某个任务的affinity属性(TaskRecord.affinity)与Activity实例的taskAffinity属性(ActivityRecord.taskAffinity)相同时,则认为找到了宿主任务。
所以,是否新建一个任务,还取决于taskAffinity属性。
如果没有为<Activity>标签设置android:taskAffinity
属性,则会继承自<Application>标签; 如果<Application>标签也没有设置,则taskAffinity就是包名。 在这种情况下,从Application 1中的Activity A以singleTask模式启动Activity B时,并不会新建任务,而是将Activity B压入已有任务的顶部,就像standard模式一样。除非将<ActivityB>设置为一个新的值:
<activity
android:name=".ActivityB"
android:taskAffinity="" />
这时候,Activity B就会在一个新的任务中启动,并且新任务的affinity属性为空
参考资料:
http://duanqz.github.io/2016-01-21-Activity-LaunchMode