Activity的启动模式(一)

1 任务栈

  1. Android任务栈又称为Task,它是一个栈结构,具有后进先出的特点,用于存放我们的activity组件。
  2. 我们每次打开一个新的activity或者退出当前的activity时都会在任务栈中入栈或者出栈一个activity组件。
  3. 当任务栈中的所有activity都被出栈后,任务栈才会被销毁。
  4. 一个app中可能不止一个任务栈。
  5. 多个app中的activity可以存在于同一个任务栈中。

每个app都有一个默认的任务栈,该任务栈的名称与app的应用包名一样。默认情况下,该app中的所有activity都运行于此任务栈中。

2 启动模式

2.1 概述

1.standard

非复用模式

以在activityA中启动activityB为例(activityB为standard启动模式),每次在activityA中启动activityB都会在activityA所在的任务栈中创建一个activityB的新实例。

2.singleTop

栈顶复用模式(如果栈顶有相同的activity,则复用)

3.singleTask

栈内复用模式(如果栈内有相同的activity,则复用)

和前面的启动模式不同,当启动一个singleTask模式的activity时,如activityA,系统会首先寻找是否存在A需要的任务栈,如果不存在,就创建此任务栈并在其中创建A的实例;

如果存在,这时要看栈中是否已有A的实例,如果有,那么系统会清除A顶部的全部activity,让A回到栈顶,如果没有,那么就创建A的实例并把A压入栈中。

4.singleInstance

单实例模式。第一次启动singleInstance模式的activityA时,会为acitivityA创建一个独占的任务栈,所谓独占就是此任务栈中只允许存在这一个activity。后面再启动activityA时,就只是复用已存在的activityA。

如果在singleInstance模式的activityA中启动standard模式的actvityB,会发生什么呢?——因为activityA所在的任务栈不允许其他任何actvity存在,因此activityB的启动模式会变成singleTask。参考上面关于startdard和singleTask模式的说明。

2.2 singleTask模式和TaskAffinity属性

在singleTask启动模式中,多次提到某个activity需要的任务栈,那么什么是activity需要的任务栈呢?就是TaskAffinity(affinity即倾向,喜好),这个属性表明了一个activity所需要的任务栈的名字,默认情况下,所有activity所需的任务栈的名字都是应用的包名,我们也可以自己指定该属性的值(必须是字符串,且中间必须包含包名分隔符”.”)。

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

2.3 为Activity指定启动模式

给activity指定启动模式有两种方式,一种是在清单文件中指定,一种是为启动activity的intent添加flag,如intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
优先级上,后一种方式更高,但两种方式其实在很多方面是有区别的。

另外,介绍一个常用的flag——FLAG_ACTIVITY_NEW_TASK:在新任务栈中启动activity,如果此activity想要的任务栈已存在,则会将该任务栈转到前台,并在该任务栈中启动activity。这会产生与singleTask启动模式相同的行为。

2.4 onNewIntent

每当复用发生时,被复用的activity及其所在的任务栈就会被移动到前台(如果它们不在前台的话),这是显而易见的,因为只有前台activity才能与用户交互。此外,被复用的activity的onNewIntent(Intent newIntent)会被调用,在此方法中我们可以获取到本次启动的新intent。

注意:当activity被复用时,如果直接使用getIntent,那么获取到的并不是此次启动的最新intent,而是最初启动时的那一个老intent。如果希望getIntent获取的是最新的intent,那么需要先在onNewIntent(Intent newIntent)方法中调用setIntent(newIntent)。

An activity will always be paused before receiving a new intent, so you can count on onResume() being called after this method(摘自官方文档).

发布了46 篇原创文章 · 获赞 38 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/al4fun/article/details/73823525