Android探索:全面分析Activity的生命周期&IntentFilter匹配规则

全面分析Activity的生命周期&IntentFilter匹配规则

转载请注明出处: https://blog.csdn.net/sange77/article/details/79922503

引言
1、Activity 的启动流程
2、生命周期的两种情况
 2.1、正常情况
 2.2、异常情况
3、如何在系统配置发生改变后,让Activity不重建?
4、隐式调用的IntentFilter匹配规则
5、想一想

引言

Android四大应用组件之一的Activity,是我们开发时最常用、最重要的,它具有多种运行状态,可你了解这些状态是如何转换的吗?它们之间有着怎样的关系呢?本文就是对Activity 生命周期工作方式的全面阐述。

1、 Activity 的启动流程

首先我们先简单了解一下Activity 的启动流程:
Activity启动请求 ——> Instrumentation通过Binder ——> ActivityManagerService通过ActivityThread ——> 生命周期不同状态
(1) 首先Activity的启动请求会交给Instrumentation来处理,然后它再通过Binder(进程通讯机制)向AMS(ActivityManagerService)发送请求;
(2) AMS内部维护着一个ActivityStack,并负责栈内Activity的状态同步,AMS通过ActivityThread去同步Activity的状态,从而完成了生命周期方法的调用。

2、生命周期的两种情况

生命周期分两种情况:正常情况下和异常情况下,不同情况下的生命周期表现会发生变化。

2.1、正常情况

Activity的生命周期
正常情况下 如上图所示,Activity一般都会经历这七个状态方法,这里可以分为三组:
- Activity的创建与销毁
onCreate:表示正在创建Activity,可以做些初始化的工作,例如 设置加载的XML布局、初始化控件和数据等;
onDestroy:表示正在销毁Activity,可以做些资源的释放和回收工作。
- Activity的可见与不可见
onStart:这时Activity已经可见,但是在后台,我们还看不到;
onStop:这时Activity已经不可见,也是在后台,可以做些不太耗时的回收工作。
- Activity的前台与后台
onResume:表示Activity可见,并且在前台,可以看到了;
onPause:表示Activity可见,切换至后台,可以做些停止动画,存储数据等不耗时的工作,跳转Activity时只有onPause方法执行完毕后,新Activity的onResume方法才会执行,然后原Activity会紧接着会执行onStop。

注意:有一种特殊情况,如果新Activity是透明主题,那么就不会执行onStop。

2.2、异常情况

  • 情况1:资源相关的系统配置发生改变时,导致Activity被杀死并重新创建

    什么意思呢?比如当前的Activity处于竖屏状态下,这时突然旋转屏幕,由于系统配置发生变化,Activity默认会被销毁然后重建。在这种情况下,系统默认会调用onSaveInstanceState方法为我们保存当前Activity的视图结构,并在Activity重启后调用onRestoreInstanceState方法为我们恢复这些数据,比如文本框输入的数据。这两个方法只会在Activity异常终止的时候调用。

  • 情况2:资源内存不足时,导致低优先级的Activity被杀死
    这种情况 方法执行过程和情况1相同,Activity的优先级从高到低是:前台Activity > 可见但非前台Activity > 后台Activity

3、如何在系统配置发生改变后,让Activity不重建?

如果不想Activity不想被重建,可以给Activity配置configChanges属性,如:

<activity
    android:name=""
    android:configChanges="orientation | screenSize"
></activity>

注意:从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,在开发针对 API 级别 13 或更高版本(正如 minSdkVersion 和 targetSdkVersion 属性中所声明)的应用时,若要避免由于设备方向改变而导致运行时重启,则除了 “orientation” 值以外,您还必须添加 “screenSize” 值。 也就是说,您必须声明 android:configChanges=”orientation|screenSize”。但是,如果您的应用面向 API 级别 12 或更低版本,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重启 Activity)。

多个值使用“|”分隔 例如,“locale|navigation|orientation”。

configChanges 配置参数说明

说明
“mcc” IMSI 移动国家/地区代码 (MCC) 发生了变化 - 检测到了 SIM 并更新了 MCC。
“mnc” IMSI 移动网络代码 (MNC) 发生了变化 - 检测到了 SIM 并更新了 MNC。
“locale” 语言区域发生了变化 — 用户为文本选择了新的显示语言。
“touchscreen” 触摸屏发生了变化。(这种情况通常永远不会发生。)
“keyboard” 键盘类型发生了变化 — 例如,用户插入了一个外置键盘。
“keyboardHidden” 键盘无障碍功能发生了变化 — 例如,用户显示了硬件键盘。
“navigation” 导航类型(轨迹球/方向键)发生了变化。(这种情况通常永远不会发生。)
“screenLayout” 屏幕布局发生了变化 — 这可能是由激活了其他显示方式所致。
“fontScale” 字体缩放系数发生了变化 — 用户选择了新的全局字号。
“uiMode” 用户界面模式发生了变化 — 这可能是因用户将设备放入桌面/车载基座或夜间模式发生变化所致。 此项为 API 级别 8 中新增配置。
“orientation” 屏幕方向发生了变化 — 用户旋转了设备。如果您的应用面向 API 级别 13 或更高级别(按照 minSdkVersion 和 targetSdkVersion 属性所声明的级别),则还应声明 “screenSize” 配置,因为当设备在横向与纵向之间切换时,该配置也会发生变化。
“screenSize” 当前可用屏幕尺寸发生了变化。它表示当前可用尺寸相对于当前纵横比的变化,因此会在用户在横向与纵向之间切换时发生变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“smallestScreenSize” 物理屏幕尺寸发生了变化。它表示与方向无关的尺寸变化,因此只有在实际物理屏幕尺寸发生变化(如切换到外部显示器)时才会变化。 对此配置的变更对应于smallestWidth 配置的变化。 不过,如果您的应用面向 API 级别 12 或更低级别,则 Activity 始终会自行处理此配置变更(即便是在 Android 3.2 或更高版本的设备上运行,此配置变更也不会重新启动 Activity)。此项为 API 级别 13 中新增配置。
“layoutDirection” 布局方向发生了变化。例如,从从左至右 (LTR) 更改为从右至左 (RTL)。 此项为 API 级别 17 中新增配置。

具体的configChanges选项配置 请参考官方文档

4、隐式调用的IntentFilter匹配规则

启动Activity有两种方式:显示调用和隐式调用。 一般我们用的最多的是显示调用,如:startActivity(Intent(this,A.class))。
使用起来比较简单。隐式调用要求Intent必须匹配IntentFilter中的过滤信息才可以成功启动Activity,过滤信息包含:action、category、data。下面针对它们分析。

1、action的匹配规则
action的匹配规则是Intent的action必须配置,且和过滤信息中的action完全匹配(大小写必须一致)。
2、category的匹配规则
Intent中的配不配置都可以,默认系统在调用startActivity或startActivityForResult的时候会为Intent加上“android.intent.category.DEFAULT”这个category,所以Intent中不配置,只要在intentFilter中配置“android.intent.category.DEFAULT”就可以匹配成功。如果intent中要配置category,数量可以不同,但必须是过滤信息中已存在的。
3、data的匹配规则
data和action的匹配规则类似,由两部分组成:mimeType(媒体类型)和URI。其中URI部分的schema默认值为content 和 file。

注意:IntentFilter匹配规则 对于Service和BroadcastReceiver规则一样,但系统建议Service使用显示调用来启动。

5、想一想

(1)dialog,fragment的工作方式又是怎样的呢?
(2)今后写Activity如何让它高效的运行?
我们明白了它的工作原理,才能更好的使用它!

致谢《Android开发艺术探索》

发布了63 篇原创文章 · 获赞 67 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/sange77/article/details/79922503
今日推荐