概述
- Activity作为四大组件之一,是使用最频繁的一种组件,正常情况下,除了Windows、Dialog和Toast,我们能见到的界面只有Activity,本章重点介绍activity的生命周期和启动模式,以及IntentFilter的匹配规则分析。
Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。
一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为“主”Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个 Activity 均可启动另一个 Activity,以便执行不同的操作。 每次新 Activity 启动时,前一 Activity 便会停止,但系统会在堆栈(“返回栈”)中保留该 Activity。 当新 Activity 启动时,系统会将其推送到返回栈上,并取得用户焦点。 返回栈遵循基本的“后进先出”堆栈机制,因此,当用户完成当前 Activity 并按“返回”按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。 (来自官方文档)
典型情况下的生命周期分析
正常情况下,Activity会经历如下生命周期:
- onCreate:表示Activity正在被创建,这是生命周期的第一个方法,在这里可以做一些初始化工作,比如加载布局资源,初始化数据等等。
- onStart:Activity正在被启动,即将开始,这是Activity已经可见了,但是还没有出现在前台,无法与用户交互.
- onResume:表示Activity已经可见了,并且出现在前台开始活动,onStart时还在后台,onResume时才在前台。
- onPause:表示这个activity正在停止,正常情况下,接着会调用onStop,此时可以做一些存储数据,停止动画等等工作,但是不能太耗时,因为会影响到新的Activity的显示,onPause必须先执行完,新的Activity的onResume才会执行。
- onStop:表示activity即将停止,可以做一些重量级的回收工作,同样不能耗时。
下面是官方的Activity生命周期图解:
各种情况下生命周期执行情况
- 对于一个Activity第一次启动:onCreate–>onStart–>onResume.
当用户打开新的Activity时:A:onPause–>B:onCreate–>B:onStart–>B:onResume–>A:onStop.
返回原来的Activity(按下返回键):
从当前Activity返回到桌面(按下Home键):onPause–onStop
从桌面返回:onRestart–>onStart–>onResume
锁屏:onPause–>onStop
解锁:onRestart–>onStart–>onResume
特殊情况下:如果新的Activity采用了透明主题,则当前Activity不会调用onStop
从整个生命周期来说,onStart和onResume、onPause和onStop看来的确差不多,甚至可以只保留其中一对,比如只保留onStart和onStop,但是这两个配对的回调分别表示不同的意义,onStart和onStop是从Activity是否可见这个角度来回调,而onResume和onPause是从Activity是否位于前台来回调的,除此之外在实际使用中没有其他明显区别。
异常情况下生命周期的分析
1.资源相关的系统配置发生改变导致Activity被杀死并重新创建
如旋转屏幕。
如果屏幕旋转,发生回调为:
onPause–>onStop–>onDestroy–>oncreate–>onstart–>onResume.
如果Activity是异常终止的,系统会调用onSaveInstanceState来保存当前Activity的状态,这个方法的调用是在onStop之前,它和OnPause没有时序关系,可能在onPause之前,也可能在之后,这个方法只会在异常终止的情况下,当Activity被重建之后,系统会调用onRestoreInstanceState,并把销毁时创建的Bundle对象作为参数传递给onRestoreInstanceState和onCreate方法,从时序上来说,onRestoreInstanceState在onStart之后。
在onSaveInstanceState和onRestoreInstanceState中系统自动为我们做了一些数据保存和恢复的工作,当Activity被销毁重建之后,系统会默认为我们恢复之前保存的视图结构,比如文本框中输入的数据,ListView的滚动位置等等,至于每一个View能保存和恢复哪些数据,则可以查看View的源码。
2.资源内存不足导致低优先级的Activity被杀死。
这种情况不好模拟,但是数据存储和恢复过程与之前的一致,不多描述。
这里介绍一下Activity的优先级情况。
前台Activity 正在与用户交互的Activity,优先级最高
可见但非前台的Activity,比如Activity弹出了一个对话框,导致Activity可见但是位于后台不能交互。
后台Activity,已经被暂停的Activity,比如执行了onStop,优先级最低
当系统内存不足时,系统会按照上述优先级去杀死目标Activity所在的进程,并在后天通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,如果一个进程中没有四大组件在执行,那么这个进程将很快被杀死,一因此,一些后台工作不适合脱离四大组件而独立运行在后台中,这样进程很容易被杀死,比较好的方法是将后台工作放入Service中保证进程有一定的优先级,这样就不会轻易的被系统杀死。
刚刚我们说过,Activity被异常杀死之后会重建,那么有没有方法不重建呢?
系统配置中有很多内容,如果当某项内容发生改变后,我们不希望系统重建Activity,可以给Activity指定configChanges属性,比如不想在屏幕旋转时重建,就可以添加orientation属性:(在Activity节点添加)
android:configChanges="orientation"
如果有多个属性 可以用 “|” 连接起来 如果我们没有配置
configChanges属性的话,当配置改变时就会重建Activity,上边的属性中,最常用的是
locale、orientation和keyboardHidden属性,需要注意的是screenSize和smallestScreenSize,它们两个比较特殊,它们的行为和编译选项有关,但和运行环境无关。
如果我们在刚刚的Demo里面添加一行
android:configChanges="orientation"
会发现屏幕旋转时还是会重建,这是因为screenSize的属性,纤细看表格中screenSize属性,所以要改为:
android:configChanges="orientation|screenSize"
再次旋转时,可见Activity并没有重建,有没有调用系统的onSaveInstanceState和onRestoreInstanceState方法,取而代之是系统调用了Activity的onConfigChanged方法。可以在这里做一些自己的特殊处理.