读书笔记|Activity的生命周期和启动模式

学习清单:

  • Activity的生命周期
  • Activity的启动模式
  • IntentFilter的匹配规则

1.1Activity的生命周期全面分析

1.1.1典型情况下的生命周期分析

正常情况下,Activity常用生命周期有以下七种

(1)onCreate:表示Activity正在被创建,生命周期的第一个方法。

(2)onRestart:表示Activity正在重新启动。

(3)onStart:表示Activity正在被启动。

(4)onResume:表示Activity是可见的,出现在前台并且开始活动。

(5)onPause:表示Activity正在停止。

(6)onStop:表示Activity即将停止。

(7)onDestory:表示Activity即将被销毁。

​ 图 1-1

一个Activity生命周期中,有可能出现这几种情况:

(1)Activity第一次启动时,回调有:onCreate -> onStart -> onResume。

(2)用户打开新的Activity或者切换到桌面时:onPause -> onStop。若Activity采用了透明主题,则Activity不会回调onStop。

(3)用户再回到原Activity时:onResume -> onStart -> onResume。

(4)用户按Back键回退时:onPause -> onStop -> onDestroy。

(5)当Activity被系统回收再打开时,生命周期与(1)一样。

(9)onCreate和onDestroy分别标识着Activity的创建和销毁,在整个生命周期中只有一次调用。

​ onStart和onStop分别标识着Activity的开始和停止,前者Activity可见,后者Avtivity不可见。

​ onResume和onPause分别标识着Activity的继续和暂停。前者Activity在前台,后者Activity在后台。

1.1.2 异常情况下的生命周期分析

1.资源相关的系统配置发生改变导致Activity被杀死并重新创建

​ 图1-2

举个例子:当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,在默认情况下,Activity就会被销毁并重新创建,其生命周期如图1-2所示。

分析:当系统配置发生更改后,Activity会被销毁,其onPause、onStop、onDestroy都会被调用,由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态(这个方法只会出现在Activity异常终止的情况下,正常情况下不会调用这个方法)。

当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数传递给onRestoreInstanceState和onCreate方法。因此,可以通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建了,如果被重建了,我们就可以取出之前保存的数据并恢复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后。

2.资源内存不足导致优先级低的Activity被杀死

Activity优先级从高到低可以分为以下三种:

(1)前台Activity ——正在和用户交互的Activity,优先级最高。

(2)可见但并非前台Activity——比如Activity中弹出一个对话框,导致Activity可见,但是位于后台无法和用户交互。

(3)后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低。

当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并在后续onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。

1.2Activity的启动模式

1.2.1 Activity 的LaunchMode

任务栈:一种“先进后出”的栈结构,存放Activity实例。

四种启动模式

(1)standard:标准模式,也是系统的默认模式,每次启动Activity都会重新创建一个新的实例,不管这个实例是否已经存在。

(2)singleTop:栈顶复用模式,如果新的Activity位于任务栈的栈顶,那么此Activity不会被重新创建,同时它的onNewIntent方法会回调。

(3)singleTask:栈内复用模式。一种单实例模式,在这种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,和singleTop一样,系统也会回调onNewIntent。

  • 比如任务栈S1中有ABC,这个时候Activity D以singleTask模式请求启动,其所需的任务栈为S2,由于S2和D的实例都不存在,系统会先创建任务栈S2,然后再创建D的实例并将其入栈到S2。
  • 假设D所需的任务栈为S1,其他情况与上述一样,由于S1存在,所以系统会直接创建D 的实例并将其入栈到S1。
  • 如果D所需的任务栈为S1,并且当前任务栈S1的情况为ADBC,此时D不会被创建,系统会把D切换到栈顶并调用其onNewIntent方法,singleTask默认具有clearTop效果,导致栈内所有在D上面的Activity全部出栈,最终S1中的情况为AD。

(4)singleInstance:单实例模式,一种加强的singleTask模式,除了singTask模式的所有特性外,还加强了一点,那就是具有此种模式的Activity只能单独地位于一个任务栈中。

举个启动模式的小例子:假设目前有两个任务栈,前台任务栈情况为AB,而后台任务栈情况为CD,假设CD的启动模式均为singleTask。现在请求启动D,那么整个后台任务都会切换到前台,这个时候按下back键的后退列表为ABCD,如图1-3。如果请求启动D而不是启动C,后退列表为ABC,如图1-4。

​ 图1-3

​ 图1-4

在singleTask启动模式中,多次提到某个Activity所需的任务栈,什么是Activity所需的任务栈?

参数TaskAffinity标识了一个Activity所需要的的任务栈的名字,默认情况下,此参数为应用的包名,可以自己指定,TaskAffinity属性主要和singleTask启动模式或者allowTaskReparenting属性配对使用,在其他情况下没有意义。

任务栈分为前台任务栈和后台任务栈,后台任务栈中的Activity处于暂停状态。

当TaskAffinity和singleTask启动模式配对使用时,它是具有该模式的Activity的目前任务栈的名字,带启动的Activity会运行在名字和TaskAffinity相同的任务栈中。

当TaskAffinity和allowTaskReparenting结合的时候,当一个应用A启动应用B 的某个Activity后,这个Activity的allowTaskReparenting属性为true的话,那么当应用B被启动后,此Activity会直接从应用A的任务栈转移到应用B的任务栈中。

1.2.2 Activity的Flags

Activity常用的标记位:

  • FLAG_ACTIVITY_NEW_TASK :为Activity指定“singleTask”启动模式。

  • FLAG_ACTIVITY_SINGLE_TOP:为Activity指定“singleTop”启动模式。

  • FLAG_ACTIVITY_CLEAR_TOP:具有此标记位的Activity,当它启动时,在同一任务栈所有位于它上面的Activity都要出栈,此标记一般会与singleTask一起出现。

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有此标记的Activity不会出现在历史Activity的列表中,等同android:excludeFromRecents = "true"

1.3IntentFilter的匹配规则

启动Activity分为两种,显示调用和隐式调用。显示调用需要明确指定被启动对象的组件信息,包括包名和类名,而隐式调用则不需要明确指定组件信息。

隐式调用:Intent 能够匹配目标组件中的action、category、data 这三个过滤信息,只有一个Intent能同时匹配这三种过滤信息才算完全匹配。

  • 只有一个intent同时匹配 action、category、 data 才算完全匹配,只有 完全匹配 才能启动activity。

  • 一个 activity 可以 有多个 intent-filter ,一个 intent 只要成功匹配任意一组intent-filter 就可以启动activity。

A.action的匹配规则

  • action的匹配要求Intent中的action 存在且必须和过滤规则中的其中action 相同

  • action 是区分大小写的。

B.category的匹配规则

  • ntent中的 category 只要有一个和 匹配规则中的category 相同就可以匹配。

  • intent 不设置 category ,也可以和其匹配,因为系统在调用 startActivity 或者 startActivity ForResult的时候会自动添加 android.intent.category.DEFAULT 这个category。

C.data的匹配规则

  • 类似于action。

  • 如果过滤规则中有data,那么intent中也必须定义可匹配的data。

  • data由 两部分组成:mimeType 和Url。

    说明:Url默认值为 content和 file。如果Intent指定完整的data,必须调用setDataAndType方法。

1.4 问题扩展

1.onStart和onResume、onPause和onStop 从描述上差不多,对我们来说有什么实质上的不同?

答:onStart和onResume是从Activity是否可见的角度来回调的,onPause和onStop是从Activity是否在前台来回调的。

2.假设当前Activity为A,如果这时用户打开一个新ActivityB,那么B的onResume和A 的onPause哪个先执行?

答:A的onPause先执行。

3.当系统配置发生变化时,Activity会被重新创建,有什么办法能够不重新创建?

答:可以给Activity指定configChanges属性。例如不想让Activity旋转时重新创建,可以给configChanges属性添加orientation这个值。

android:configChanges="orientation"

本文参考:

​ 《Android开发艺术探索》

IntentFilter的匹配规则

猜你喜欢

转载自blog.csdn.net/qq_44830568/article/details/108501112