一.启动模式

Activity 一共有四种 launchMode :standardsingleTopsingleTasksingleInstance

Standard 模式(默认模式)

  1. 说明:每次启动一个 Activity 都会又一次创建一个新的实例入栈,无论这个实例是否存在。
  2. 生命周期:每次被创建的实例 Activity 的生命周期符合典型情况,它的 onCreate 、onStart 、onResume 都会被调用。
  3. 举例:此时 Activity 栈中以此有 A 、B 、C 三个 Activity ,此时C处于栈顶,启动模式为 Standard 模式。若在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是还有一个 C Activity 进入栈中,成为栈顶。

SingleTop 模式(栈顶复用模式)

  1. 说明:分两种处理情况:须要创建的 Activity 已经处于栈顶时,此时会直接复用栈顶的 Activity 。不会再创建新的 Activity ;若须要创建的 Activity 不处于栈顶,此时会又一次创建一个新的 Activity 入栈,同 Standard 模式一样。
  2. 生命周期:若情况一中栈顶的 Activity 被直接复用时,它的 onCreate 、onStart 不会被系统调用,由于它并没有发生改变。可是一个新的方法 onNewIntent 会被回调( Activity 被正常创建时不会回调此方法)。
  3. 举例:此时 Activity 栈中以此有 A 、B 、C 三个 Activity ,此时 C 处于栈顶,启动模式为 SingleTop 模式。情况一:在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是直接复用栈顶的 C Activity。情况二:在 C Activity 中加入点击事件,须要跳转到还有一个 A Activity。结果是创建一个新的 Activity 入栈。成为栈顶。

SingleTask 模式(栈内复用模式)

  1. 说明:若须要创建的 Activity 已经处于栈中时,此时不会创建新的 Activity ,而是将存在栈中的 Activity 上面的其他 Activity 所有销毁,使它成为栈顶。
  2. 如果是在别的应用程序中启动它,则会新建一个 task ,并在该task中启动这个 Activity ,singleTask 允许别的 Activity 与其在一个 task 中共存,也就是说,如果我在这个 singleTask 的实例中再打开新的 Activity ,这个新的 Activity 还是会在 singleTask 的实例的 task 中。
  3. 生命周期:同 SingleTop 模式中的情况一同样。仅仅会又一次回调 Activity 中的 onNewIntent 方法
  4. 举例:此时 Activity 栈中以此有 A 、B 、C 三个 Activity 。此时 C 处于栈顶,启动模式为 SingleTask 模式。情况一:在 C Activity 中加入点击事件,须要跳转到还有一个同类型的 C Activity 。结果是直接用栈顶的 C Activity 。情况二:在 C Activity 中加入点击事件,须要跳转到还有一个 A Activity 。结果是将 A Activity 上面的 B 、C 所有销毁,使 A Activity 成为栈顶。

SingleInstance 模式(单实例模式)

  1. 说明:SingleInstance 比较特殊,是全局单例模式,是一种加强的 SingleTask 模式。它除了具有它所有特性外,还加强了一点:只有一个实例,并且这个实例独立运行在一个 task 中,这个 task 只有这个实例,不允许有别的 Activity 存在。
  2. 这个经常使用于系统中的应用,比如 Launch 、锁屏键的应用等等,整个系统中仅仅有一个!所以在我们的应用中一般不会用到。了解就可以。
  3. 举例:比方 A Activity 是该模式,启动 A 后。系统会为它创建一个单独的任务栈,由于栈内复用的特性。兴许的请求均不会创建新的 Activity ,除非这个独特的任务栈被系统销毁。

二.启动模式的使用方式

在 Manifest.xml 中指定 Activity 启动模式

  1. 一种静态的指定方法
  2. 在 Manifest.xml 文件里声明 Activity 的同一时候指定它的启动模式
  3. 这样在代码中跳转时会依照指定的模式来创建 Activity 。

启动 Activity 时。在 Intent 中指定启动模式去创建 Activity

  1. 一种动态的启动模式
  2. 在 new 一个 Intent 后
  3. 通过 Intent 的 addFlags 方法去动态指定一个启动模式。

注意:以上两种方式都能够为 Activity 指定启动模式,可是二者还是有差别的。

  1. 优先级:动态指定方式即另外一种比第一种优先级要高,若两者同一时候存在,以另外一种方式为准。
  2. 限定范围:第一种方式无法为 Activity 直接指定 FLAG_ACTIVITY_CLEAR_TOP 标识,另外一种方式无法为 Activity 指定 singleInstance 模式。

三.启动模式的实际应用场景

这四种模式中的 Standard 模式是最普通的一种,没有什么特别注意。而 SingleInstance 模式是整个系统的单例模式,在我们的应用中一般不会应用到。所以,这里就具体解说 SingleTop 和 SingleTask 模式的运用场景:

SingleTask 模式的运用场景

  1. 最常见的应用场景就是保持我们应用开启后仅仅有一个 Activity 的实例。
  2. 最典型的样例就是应用中展示的主页( Home 页)。
  3. 假设用户在主页跳转到其他页面,运行多次操作后想返回到主页,假设不使用 SingleTask 模式,在点击返回的过程中会多次看到主页,这明显就是设计不合理了。

SingleTop 模式的运用场景

  1. 假设你在当前的 Activity 中又要启动同类型的 Activity
  2. 此时建议将此类型 Activity 的启动模式指定为 SingleTop ,能够降低Activity的创建,节省内存!

注意:复用 Activity 时的生命周期回调

  1. 这里还须要考虑一个 Activity 跳转时携带页面參数的问题。
  2. 由于当一个 Activity 设置了 SingleTop 或者 SingleTask 模式后,跳转此 Activity 出现复用原有 Activity 的情况时,此 Activity 的 onCreate 方法将不会再次运行。onCreate 方法仅仅会在第一次创建 Activity 时被运行。
  3. 而一般 onCreate 方法中会进行该页面的数据初始化、UI 初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题
  4. 若页面展示的数据就是通过 getInten() 方法来获取,那么问题就会出现:getInten() 获取的一直都是老数据,根本无法接收跳转时传送的新数据!

以下,通过一个样例来具体解释:

以上代码中的 CourseDetailActivity 在配置文件里设置了启动模式是 SingleTop 模式,依据上面启动模式的介绍可得知,当 CourseDetailActivity 处于栈顶时。

再次跳转页面到 CourseDetailActivity 时会直接复用原有的 Activity ,并且此页面须要展示的数据是从 getIntent() 方法得来,可是 initData() 方法不会再次被调用,此时页面就无法显示新的数据。

当然这样的情况系统早就为我们想过了,这时我们须要另外一个回调 onNewIntent(Intent intent)方法。此方法会传入最新的 intent ,这样我们就能够解决上述问题。这里建议的方法是又一次去 setIntent 。然后又一次去初始化数据和 UI 。

代码例如以下所看到的:

这样,在一个页面中能够反复跳转并显示不同的内容。

四.快速启动一个 Activity

这个问题其实也是比较简单的,就是不要在 Activity 的 onCreate 方法中执行过多繁重的操作,并且在 onPasue 方法中同样不能做过多的耗时操作。

五.Activity 的 Flags

  • 标记位既能够设定Activity的启动模式,如同上面介绍的,在动态指定启动模式,比方 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_SINGLE_TOP 等。它还能够影响 Activity 的运行状态 ,比方 FLAG_ACTIVITY_CLEAN_TOPFLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 等。
  • 以下介绍几个基本的标记位,切勿死记,理解几个就可以,须要时再查官方文档。

FLAG_ACTIVITY_NEW_TASK

作用是为 Activity 指定 “SingleTask” 启动模式。跟在 AndroidMainfest.xml 指定效果同样

FLAG_ACTIVITY_SINGLE_TOP

作用是为 Activity 指定 “SingleTop” 启动模式,跟在 AndroidMainfest.xml 指定效果同样。

FLAG_ACTIVITY_CLEAN_TOP

  1. 具有此标记位的 Activity ,启动时会将与该 Activity 在同一任务栈的其他 Activity 出栈。
  2. 一般与 SingleTask 启动模式一起出现。
  3. 它会完毕 SingleTask 的作用。
  4. 但事实上 SingleTask 启动模式默认具有此标记位的作用

FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

  1. 具有此标记位的 Activity 不会出如今历史 Activity 的列表中
  2. 使用场景:当某些情况下我们不希望用户通过历史列表回到 Activity 时,此标记位便体现了它的效果。
  3. 它等同于在 xml 中指定 Activity 的属性.

六.onNewInstent()方法什么时候执行

这个是启动模式中的了,当此 Activity 的实例已经存在,并且此时的启动模式为 SingleTask 和 SingleInstance ,另外当这个实例位于栈顶且启动模式为 SingleTop 时也会触发 onNewInstent()。

七.启动流程