Activity有四种启动模式:Standard、SingleTop、SingleTask、SingleInstance.
Standard - 标准模式
默认的系统模式。每次启动一个Activity都会重新创建一个新的实例。这种模式下,谁启动了该模式的Activity,这个Activity就存在于启动他的Activity的任务栈中。
SingleTop - 栈顶复用模式
-
如果要开启的Activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用Activity的onNewIntent()方法。避免栈顶的Activity被重复创建。
-
如果栈顶或栈中不存在该Activity的实例,则情况同Standard模式。
SingleTask - 栈内复用模式
Activity只会在任务栈里面存在一个实例。如果要激活的Activity,在任务栈里面已经存在,就不会创建新的Activity,而是复用这个已经存在的Activity,调用 onNewIntent() 方法,并且清空这个Activity任务栈上面所有的Activity。
这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。
注:尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。
SingleInstance - 全局唯一
该模式具备singleTask模式的所有特性外,与它的区别就是,这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例,由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。
taskAffinity
先介绍一下taskAffinity的属性。
与 Activity 有着亲和关系的任务。从概念上讲,具有相同亲和关系的 Activity 归属同一任务(从用户的角度来看,则是归属同一“应用”)。 任务的亲和关系由其根 Activity 的亲和关系确定。
亲和关系确定两件事 - Activity 更改到的父项任务(allowTaskReparenting 属性)和通过 FLAG_ACTIVITY_NEW_TASK 标志启动 Activity 时将用来容纳它的任务。
每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该 Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果 Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根 Activity的taskAffinity的值。
注意:前方有坑!
-
Standard模式和SingleTop模式都是在原任务栈中新建Activity实例,不会创建新的Task,即使你指定了taskAffinity属性。
-
在singleTop模式下我们需要同时在onCreate() 和 onNewIntent()中处理发来的intent,以满足不同情况。
-
使用SingleTask或者FLAG_ACTIVITY_NEW_TASK启动activity的时候,如果没有指定taskAffinity,系统并不会新建一个Task,而是在当前栈的栈顶(通过dumpsys activity activities 命令可以看到)。只有指定了不同的taskAffinity,才会新建Task。
-
使用SingleInstance,如果没有指定taskAffinity,系统仍然会新建一个Task(通过dumpsys activity activities 命令可以看到),但是,从设备的最近任务列表中,却只能看到一个任务,而只有指定了taskAffinity,才能看到两个不同的任务。
网友评论