经历过多家面试的人或许可以看出。activity 的启动模式这个知识点或许是所有面试官都绕不开的问题之一了。一个应用程序是由一个或多个 activity 组成。它承载了 Ui 界面,与用户交互。可以说开发 Android 应用程序,activity 是必不可少的一个部分。今天先不讨论 activity 的具体功能。让我们从它是如何启动开始,一步步的深入了解它。
在说启动模式之前,我们应该先了解一些 Android 任务栈的概念。在我们打开应用程序的时候,系统会自动创建一个任务栈用于存储当前程序中的 Activity。任务栈有先进后出的原则,即先打开的 activity 位于栈底后入的 activity 位于栈顶。而在结束应用时后入的 activity 先出栈先入的 activity 后出栈。在所有 activity 被清除后,任务栈会被销毁,程序成功退出。也是由于这个先入后出的原则造成了一些小麻烦,举个例子:当你依次打开了 A、B、C 三个 Activity 时。在使用默认的启动模式之下,如果你想从 C 直接回到 A 。这时你必须先回到 B 再回到 A。这样会给用户带来很不好的用户体验。还有,如果你多次创建同一个 activity 会造成数据冗余,甚至是内存溢出。由于以上的这些原因,Android 引入了启动模式。
启动模式(launchMode)在多个 Activity 跳转的过程中扮演着重要的角色,它可以决定是否生成新的 Activity 实例,是否重用已存在的 Activity 实例,是否和其他 Activity 实例公用一个 task 里。这里简单介绍一下 task 的概念,task 是一个具有栈结构的对象,一个 task 可以管理多个 Activity,启动一个应用,也就创建一个与之对应的 task。
Activity 有四种启动模式:standard 、singleTop 、singleTask 、singleInstance 。
他们分别承担这不同的工作情景。下面我们来一个个介绍:
Standard 模式:
系统默认的启动模式,无需刻意指定。会在每次启动活动时都创建一个新的实例。
A --> A ,存在两个 A 实例
A --> B --> A ,会存在两个 A 实例。
SingleTop 模式:
在启动活动时会先查看需要打开的活动是否位于栈顶,是则复用,否的话会调用这个活动的 onNewIntent()方法创建新的实例。
A --> A ,复用已经存在的 A 实例 此时只存在一个 A实例
A --> B --> A , 存在两个 A 实例
SingleTask 模式:
在启动活动时,若已经存在运行目标活动的 Task ,那这个活动实例会被调到前台,并且会调用这个活动的 onNewIntent()。无论该活动是否位于栈顶。如果当前活动不是位于栈顶时,会移除当前活动之上的所有活动使其位于栈顶位置。如果设置的 taskAffinity 属性指定的任务栈不是当前任务栈,并且不存在。则会创建相应的任务栈来存放该活动。
A --> A ,存在一个 A 实例。A -->B --> A ,存在一个 A 实例,并且会把 B 实例移出任务栈。
SingleInstance 模式:
这种模式具备了 SingleTask 模式的所有特性。不同的是,这种模式下活动会单独占用一个任务栈,不会在其之上创建任何活动。