《Android开发艺术探索》Activity的生命周期和启动模式

Activity的生命周期

《Android开发艺术探索》Activity的生命周期和启动模式_第1张图片
timg.jpg

Activity的启动模式

《Android开发艺术探索》Activity的生命周期和启动模式_第2张图片
timg.jpg

(1) standard:标准模式

《Android开发艺术探索》Activity的生命周期和启动模式_第3张图片
timg.jpg

这也是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。被创建的实例的生命周期符合典型情况下Activity的生命周期,如上节描述,它的onCreate, onStart,onResume都会被调用。这是一种典型的多实例实现,一个任务栈中可以有多个实例,每个实例也可以属于不同的任务栈。在这种模式下,谁启动了这个Activity,那么这个Activity就运行在启动它的那Activity在中比如Activity A启动了Activity B (B是标准模式),那么B就会进入到A所在的栈中。当我们用ApplicationContext去启动standard模式的Activity的时候会报错,错误如下:

 E/Androl dRunt ime(674) android util. Androi dRuntimeExcept ion:  
 Callining startActivity from outsIde of an Activity context requires the FLAG_ACTIVITY_NEN_TASK flag. Is this really what you want?

相信这句话读者一定不陌生,这是因为 standard模式的 Activity默认会进入启动它的Activity所属的任务栈中,但是由于非 Activity类型的 Context(如 ApplicationContext)并没有所谓的任务栈,所以这就有问题了。解决这个问题的方法是为待启动 - Activity指定 FLAG ACTIVITY_ NEW TASK标记位,这样启动的时候就会为它创建一个新的任务极这个时候待启动 Activity实际上是以 single Task模式启动的,读者可以仔细体会。

(2) single Top:栈顶复用模式

《Android开发艺术探索》Activity的生命周期和启动模式_第4张图片
timg.jpg

在这种模式下,如果新 Activity已经位于任务栈的栈顶,那么此 Activity不会被重新创建,同时它的 onNew Intent方法会被回调,通过此方法的参数我们可以取出当前请求的信息。

需要注意的是,这个 Activity的 onCreate、 onStart不会被系统调用,因为它并没有发生改变。如果新 Activity的实例已存在但不是位于栈顶那么新 Activity仍然会重新重建。

举个例子

  • 假设目前内的情况为ABCD,其中ABCD为四个 Activity,A位于线底,D位干栈顶
  • 这个时候假设要再次启动D,如果D的启动模式为 singleTop,那么栈内的情况仍然为ABCD;如果D的启动模式为 standard
  • 那么由于D被重新创建,导致栈内的情况就变为 ABCDD

(3) single Task:栈内复用模式

《Android开发艺术探索》Activity的生命周期和启动模式_第5张图片
timg.jpg

这是一种实例模式,在这种模式下,只要Activity在一个中存在,那么多次启动此 Activity都不会重新创建实例,和singleTop一样,系统也会回调其onNewIntent.具体一点,当一个具有 single Task模式的 Activity请求启动后比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,就重新创建个任务栈,然后创建A的实例后把A放到栈中。如果存在A所需的任务栈,这时要看A是否在栈中有实例存在,如果有实例存在,那么系统就会把A调到栈顶并调用它的onNewIntent方法,如果实例不存在,就创建A的实例并把A压入栈中。举几个例子:

  • 比如目前任务栈S1中的情况为ABC,这个时候 Activity D以 I single Task模式请求启动,其所需要的任务线为S2,由于S2和D的实例均不存在,所以系统会先创建任务栈S2,然后再创建D的实例并将其入栈到S2.
  • 另外一种情况,假设D所需的任务栈为S,其他情况如上面例子1所示,那么由于S1已经存在,所以系统会直接创建D的实例并将其入栈到S1.
  • 如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,根据栈内复用的
    原则,此时D不会重新创建,系统会把D切换到栈顶并调用其 onNewIntent方法,
    同时由于 single Task默认具有 clear Top的效果,会导致栈内所有在D上面的 Activity
    全部出栈,于是最终S1中的情况为AD。这一点比较特殊,在后面还会对此种情况
    详细地分析。
    通过上述3个例子,读者应该能比较清晰地理解 single Task的含义了。

(4)singleInstance:单实例模式

这是一种加强的 single Task模式,它除了具有 single Task
模式的所有特性外,还加强了一点,那就是具有此种模式的 Activity只能单独地位于一个
任务栈中,换句话说,比如 Activity A是 single模式,当A启动后,系统会为它创
建一个新的任务栈,然后A独自在这个新的任各栈中,由于线内复用的特性,后续的请求
均不会创建新的 Activity.,除非这个独特的任务栈被系统销毁了。上面介绍了几种启动模式,这里需要指出一种情况,我们假设目前有2个任务栈,前台任务栈的情况为AB,而后台任务栈的情况为CD,这里假设CD的启动模式均为singleTask.现在请求启动D,那么整个后台任务栈都会被切换到前台,这个时候整个后退列表变成了ABCD。当用户按back键的时候,列表中的 Activity会一一出栈,如图1-7所示。如果不是请求启动D而是启动C,那么情况就不一样了。

IntentFliter的匹配规则

1.action的匹配规则

action是一个字符串,系统预定义了一些action,同时我们也可以在应用中定义自己的action。action的匹配规则是Intent中的action必须能够和过滤规则中的action匹配,这里说的匹配是指 action的字符串值完全一样。一个过滤规则中可以有多个 action,那么只要Intent中的 action能够和过滤规则中的任何一个 action相同即可匹配成功。针对上面的过滤规则,只要我们的 Intent中 action值为“com.ryg. charpter_1.c”或者“com.ryg. charpter_1.d”都能成功匹配。需要注意的是, Intent中如果没有指定 action,那么匹配失败。

总结一下

action的匹配要求 Intent中的 action存在且必须和过滤规则中的其中一action相同,这里需要注意它和category匹规则的不同。另外,actior区分大小写,大小写不同字符串相同的 action会匹配失败。

2. category的匹配规则

category是一个字符串,系统预定义了一些 category,同时我们也可以在应用中定义自己的 category. category的匹配规则和 action不同,它要求tent中如果含有 category.,那么所有的 calegory都必须和过滤规则中的其一个 category相同。换句话说, Intent中如果出现了 category,不管有几个 category,对于每个 category来说,它必须是过滤规则中已经定义了的 category.当然, Intent中可以没有 category,如果没有 category的话,按照上面的描述,这个 Intent仍然可以匹配成功。这里要注意下它和 I action匹配过程的不同, action是要求 Intent中必须有一个 action且必须能够和过滤规则中的某个 acton相同,而 category要求 Intent可以没有 category,但是如果你一旦有 category,不管有几个,每个都要能够和过滤规则中的任何一个 category相同。为了匹配前面的过滤规则中的 category,我们可以写出下面的

 Intent, intent addcategory (com ryg category.)ak Intent. addcategory (com. rygategory.d)

亦或者不设置 I category:为什么不设置 category也可以匹配呢?原因是系统在调用 startActivity或者 start Activity For Result的时候会默认为Intent加上<“ android. intentcategory. DEFAULT”>这个 category,所以这个 ategory就可以匹配前面的过滤规则中的第三个 category同时,为了我们的 activity能够接收隐式调用,就必须在 Intent- filter中指定这个 category,原因刚才已经说明了。

3. data的匹配规则

data的匹配规则和 I action类似,如果过滤规则中定义了data,那么 Intent中必须也要定义可匹配的data.在介绍data的匹配规则之前,我们需要先了解一下data的结构,因为data稍微有些复杂。

data的语法如下所示:
     

未完待续...

你可能感兴趣的:(《Android开发艺术探索》Activity的生命周期和启动模式)