在总结Activity的启动模式前,我们先来认真一下android中的任务与返回栈模式。
什么是任务?
Android中的任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。如图,即是一个完整的任务栈流程。
Activity 和任务的默认行为总结如下:
1.当 Activity A 启动 Activity B 时,Activity A 将会停止,但系统会保留其状态(例如,滚动位置和已输入表单中的文本)。如果用户在处于 Activity B 时按“返回”按钮,则 Activity A 将恢复其状态,继续执行。
2.用户通过按“主页”按钮离开任务时,当前 Activity 将停止且其任务会进入后台。 系统将保留任务中每个 Activity 的状态。如果用户稍后通过选择开始任务的启动器图标来恢复任务,则任务将出现在前台并恢复执行堆栈顶部的 Activity。
3.如果用户按“返回”按钮,则当前 Activity 会从堆栈弹出并被销毁。 堆栈中的前一个 Activity 恢复执行。销毁 Activity 时,系统不会保留该 Activity 的状态。
android的多任务模式中,任务的状态与行为各有不同,那我们如何去管理任务,并且控制任务内部元素的状态呢? 这就讲到了Activity的启动模式、
Activity的启动模式
1.定义启动模式
Activity的启动模式定义有两种, 一种在AndroidManifast.xml中定义launchMode属性,一种即在startActivity的Intent参数中声明新 Activity 如何(或是否)与当前任务关联。 如果一个Activity在清单中定义了其关联方式,并且startActivity中的Intent也已经声明,则Intent中定义的优先级要高于清单文件。
2.启动模式介绍
清单文件中的属性:
"standard": 默认。系统在启动 Activity 的任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。
"singleTop":如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的onNewIntent()方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例(但前提是位于返回栈顶部的 Activity 并不是 Activity 的现有实例)。
例如,假设任务的返回栈包含根 Activity A 以及 Activity B、C 和位于顶部的 D(堆栈是 A-B-C-D;D 位于顶部)。收到针对 D 类 Activity 的 Intent。如果 D 具有默认的"standard"启动模式,则会启动该类的新实例,且堆栈会变成 A-B-C-D-D。但是,如果 D 的启动模式是"singleTop",则 D 的现有实例会通过onNewIntent()接收 Intent,因为它位于堆栈的顶部;而堆栈仍为 A-B-C-D。但是,如果收到针对 B 类 Activity 的 Intent,则会向堆栈添加 B 的新实例堆栈变成了A-B-C-D-B,即便其启动模式为"singleTop"也是如此。
"singleTask" :系统创建新任务并实例化位于新任务底部的 Activity。但是,如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的onNewIntent()方法向其传送 Intent,而不是创建新实例。一次只能存在 Activity 的一个实例。 注:尽管 Activity 在新任务中启动,但是用户按“返回”按钮仍会返回到前一个 Activity。
"singleInstance":与"singleTask"相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。
Intent中的参数:
FLAG_ACTIVITY_NEW_TASK : 同清单属性中的singleTask
FLAG_ACTIVITY_SINGLE_TOP : 同清单属性中的singleTop
FLAG_ACTIVITY_CLEAR_TOP : 如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并通过onNewIntent()将此 Intent 传递给 Activity 已恢复的实例(现在位于顶部),而不是启动该 Activity 的新实例。