Activity启动模式

任务栈

Android是以栈来管理多个Activity的,根据先进先出的原则,当切换到新的Activity时,该Activity就会被压入栈,成为栈顶;当点击返回键时,栈顶的Activity出栈,紧随其后的Activity就成为新的栈顶。

一个手机在同一时刻会有多个任务栈,但只有一个栈在前台,其他的栈都在后台。

任务栈是跨应用的,就是说任务栈并非存放唯一一个APP的所有Activity,这是为了保持用户操作的连贯性,可在APP1打开APP2像打开APP1本身的Activity一样连贯。

TaskAffinity

TaskAffinity是<activity>的一个属性,用于标识此Activity所需要的任务栈的名字,默认值为包名。

TaskAffinity属性主要和singleTask启动模式或allowTaskReparenting属性配对使用,在其他情况下没有意义。

TaskAffinity与singleTask

指定Activity要运行在名字和TaskAffinity相同的任务栈中。

TaskAffinity和allowTaskReparenting

启动指定了TaskAffinity属性,而且allowTaskReparenting = true的Activity时,若发现其所需的任务栈不存在,则它可运行在当前任务栈上,即使该栈的名称与TaskAffinity属性值不同。

如果随后该Activity所需的任务栈(栈名与TaskAffinity属性值相同)被创建,则自动把它转移到这个任务栈上。

Activity的4种启动模式

standard

标准模式,系统的默认模式。

每次启动一个Activity都会重新创建一个新的实例。

standard模式的Activity默认会进入启动它的Activity所属的任务栈中。若是非Activity类型的Context来启动,就必须指定FLAG_ACTIVITY_NEW_TASK标志位,让待启动Activity进入一个新创建的任务栈中,这是因为非Activity类型的Context没有所属的任务栈

大多数Activity都是使用此启动模式。

singleTop

栈顶复用模式。

若新Activity已有实例位于任务栈的栈顶,那么就不会再创建此Activity实例,而是回调其onNewIntent(),把当前请求的信息传递进去。

若新Activity已有实例但不是位于栈顶,那么会创建该Activity实例。

singleTask

栈内复用模式。

启动singleTask模式的Activity的工作流程是:

  1. 系统首先会寻找是否存在它想要的任务栈,若不存在该任务栈,则创建指定名称的任务栈,接着创建此Activity实例并放入该栈中。

  2. 若存在该任务栈,则检测此栈中是否存在此Activity实例。

  3. 若实例存在,将它上面的Activity干掉使其变成栈顶,接着调用它的onNewIntent();否则,创建此Activity并放入该栈中。

常用于App的主界面,如浏览器的主界面,即不管从多少个地方启动浏览器,都只会启动一个主界面。

singleInstance

单实例模式。

此模式是一种加强的singleTask模式,它除了具有singleTask模式的所有特性外,还有它只能单独地位于一个任务栈中。

一旦该模式的Activity实例已经存在于某个栈中,任何应用再启动该Activity时都会重用该栈中的实例(会调用实例的onNewIntent())。

注意,singleInstance独占一个任务栈。如果此模式的Activity若启动其他Activity,这个新Activity会运行在其他任务栈中。

常用于闹铃提醒等,让多个应用共享该栈中的该Activity实例。

指定Activity的启动模式

可以在AndroidManifest.xml中指定Activity的启动模式。

<!-- 可选值有:standard、singleTop、singleTask、singleInstance -->
<activity
    android:launchMode="singleTop" />
1
2
3

也可以在Intent中设置标志位来指定Activity的启动模式。

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1

第二种方式的优先级更高,即两种方式同时存在时,以第二种方式为准。

第一种方式无法为Activity设定FLAG_ACTIVITY_CLEAR_TOP,而第二种方式无法为Activity指定singleInstance模式。

Activity的Flags

Intent类中定义了很多的Activity标志位,下面将介绍常用的几个。

用于设定Activity的启动模式:

  • FLAG_ACTIVITY_NEW_TASK:其作用与singleTask启动模式一致。

  • FLAG_ACTIVITY_SINGLE_TOP:其作用与singleTop启动模式一致。

影响Activity的运行状态的有:

  • FLAG_ACTIVITY_CLEAR_TOP:当此Activity启动时,在同一个任务栈中所有位于它上面的Activity都要出栈。singleTask启动模式默认就具有这个效果。

  • FLAG_EXCLUDE_FROM_RECENTS:与android:excludeFromRecents="true"一致。此Activity不会出现在历史Activity的列表中。

  • FLAG_ACTIVITY_CLEAR_TASK:当此Activity启动时,在同一个任务栈中的其他Activity都要被清除,它会成为该栈的根。这个标志必须与FLAG_ACTIVITY_NEW_TASK一起使用。