Task是一些Activity的集合,以Activity栈的形式存放。因此,Task是概念上的,Activity栈是实体上的。
可以说,新启动了一个Task就是新建了一个Activity栈,来存放这个Task内的Activity。
<activity
android:name="com.example.test.SecondActivity"
android:launchMode="singleTask"
/>
Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
把一个activity启动模式设置为为singleTask,只是意味着framework在启动该activity时把它标识为可在一个新任务中启动,至于是否在一个新任务中启动,那可不一定了!是需要条件的,什么条件呢?请看下文分解~
假设下面的跳转关系:
MainActivity -> SecondeActivity -> ThirdActivity
其中,SecondeActivity被设置了singleTask的启动模式,MainActivity和ThirdActivity都不做任何操作,保持默认,即standard模式
那么跳到ThirdActivity后,当前的Activity栈情况从顶到底部是:
ThirdActivity、SecondeActivity、MainActivity
也就是说依然按照正常压栈的顺序,和standard模式一样。并不是按照谷歌官方解释的,容易误解为新建了一个Task,并用新的栈存放SecondeActivity。这是误解。
那么,真的和standard模式一样吗?
还是有不同的,不然弄这个模式干嘛。
不同之处,用下面的例子说明:
假设下面的跳转关系:
MainActivity -> SecondeActivity -> ThirdActivity -> ForthActivity ->SecondeActivity
其中,SecondeActivity被设置了singleTask的启动模式,其余Activity都不做任何操作,保持默认,即standard模式
那么跳到SecondeActivity后,当前的Activity栈情况从顶到底部是:
SecondeActivity、MainActivity
没错,SecondeActivity以上的 ThirdActivity、ForthActivity都被销毁了。
也就是说,重用了栈里面已有的 SecondeActivity ,并且把它上面的 activity 都清除了,从而使得它暴露在最上面。
顺便说一下,最后一个SecondeActivity的启动没有调用onCreate,而是依次调用了onRestart、onStart、onNewIntent、onResume这些生命周期方法。
被标记为singleTask的Activity,在启动的时候如果当前没有实例,就和standard模式一样,直接压栈到当前activity上;如果已经有实例了,就把该目标Activity实例上面的activity都清除,从而将目标Activity暴露到最上面,调用了其onNewIntent方法
上面的两个例子都在我们认知范围内,还比较熟悉。但是这个taskAffinity想必就不太熟悉了。
taskAffinity是标记当前activity附属到哪个task上的。
默认情况下,也就是不配置,taskAffinity取的是应用的包名。
<activity android:name="com.example.test.SecondActivity"
android:launchMode="singleTask"
android:taskAffinity="com.example.test.second">
</activity>
配合singleTask使用,意味着被这两个属性标记的activity可以被指定到一个新的task里。
假设下面的跳转关系:
MainActivity -> SecondeActivity -> ThirdActivity
其中,SecondeActivity被设置了singleTask的启动模式,并且配置了taskAffinity属性,MainActivity和ThirdActivity都不做任何操作,保持默认,即standard模式
那么跳到ThirdActivity后,当前的Activity栈情况从顶到底部是:
Task1: ThirdActivity、MainActivity
Task2: SecondeActivity
可以看到,SecondeActivity被创建到了新的栈里。
于是,可以得出之前疑问的答案,什么条件下设置为singleTask的activity会被创建到新的task呢?
答案是,同时被指定了另一个taskAffinity属性值的时候。
现在处于onResume的activity是ThirdActivity,如果这时候按返回键呢?activity的显示顺序会是什么样呢?
答案正如上面Task1、Task2栈的排列顺序,ThirdActivity弹出后,MainActivity显示;再按返回键,MainActivity弹出后,SecondeActivity显示。
可以看出,新建的Task处于下方。
参考文章:https://blog.csdn.net/zhangjg_blog/article/details/10923643