以下内容摘抄自作者:任玉刚所著的《Android开发艺术探索》
生命周期
-
OnCreate
表示Activity正在被创建。可在这个方法中做一些初始化的工作,如初始化数据initData(),加载布局界面setContentView()等等。 -
onRestart
表示Activity正在重新启动。一般但界面从不可见变为可见时被调用。如切换到Home界面或打开新Activity后,该界面将会调用onPause()和onStop()方法,又重新回到该界面时,该方法被调用。 -
onStart
表示Activity正在启动。此时的Activity已经可见了,但是我们还看不到,此时还无法与用户交互。 -
onResume
表示Activity已经出现在前台,我们已经可以看的到界面了,此时可以与用户交互了。 -
onPause
表示Activity正在停止,紧接着onStop()就会被调用。在这里可以做一些不太耗时的操作,比如存储数据,结束动画等。这个方法执行完,新Activity的onResume()方法才会执行。极端情况下,快速返回该界面会调用onResume()。 -
onStop
表示Activity即将停止,可以执行一些相比onPause()中更复杂点的回收工作,但是与onPause()一样,不能太耗时。 -
onDestroy
表示Activity即将被销毁,可以在这里做最后的资源释放和回收。
特殊情况说明
-
打开新的Activity或者切换回桌面时
回调调用顺序为onPause() -> onStop()。注意:当新打开的Activity使用透明主题时,上一个Activity没有被遮挡,仍为可见状态,将不调用onStop()方法。 -
当Activity被系统回收后再次打开时
生命周期将从onCreate()开始。注意:只是生命周期一样,不代表所有过程都相同。
异常情况下的生命周期
- 资源相关的系统配置发生改变,导致Activity被杀死并重建(如旋转屏幕)
在默认情况下,如果我们的Activity不做特殊处理,那么当系统配置发生改变后,Activity就会被销毁并重新创建,生命周期如下:
系统配置发生改变后,Activity被销毁,回调方法onPause()、onStop()、onDestroy()都会被相继调用。
由于是异常状态被终止,系统会调用onSaveInstanceState()来保存当前Activity的状态。这个方法的调用时机在onStop()之前,与onPause()没有先后关系。这个方法只会出现在Activity被异常终止的情况下被调用。
当Activity被重新创建之后,系统会调用onRestoreInstanceState(),并把onSaveInstanceState()中所保存的Bundle对象作为参数传给onRestoreInstanceState()和onCreate()方法,因此可以通过该方法判断Activity是否是被重建的。onRestoreInstanceState()调用时序在onStart()方法之后。
除了主动保存恢复数据之外,系统还为我们自动保存恢复一些数据如:Activity的视图结构,其中包括文本框中用户输入的数据、ListView的滚动位置等。这些View相关的状态,系统都可以默认恢复。具体想知道每个View中可以恢复哪些数据,查看每个View其中的onSaveInstanceState()和onRestoreInstanceState()。
View的保存与恢复在系统的工作流程是这样的:Activity意外终止,调用onSaveInstanceState()保存数据后,会委托Window去保存数据,接着Window会委托它上面的顶级容器去保存。顶级容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶级容器再去一一通知它的子元素来保存。这是一种典型的委托思想:上层委托下层,父容器委托子元素去处理事务。
使用方法如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
String saveTest = savedInstanceState.getString("save_test");
Log.d("MainActivity", "save_test in onCreate(): " + saveTest);
}
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("save_test", "这里存了一部分数据");
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String saveTest = savedInstanceState.getString("save_test");
Log.d("MainActivity", "save_test in onRestoreInstanceState() : " + saveTest);
}
注意:在系统异常销毁(如:旋转屏幕)时,该Activity虽被系统销毁,但有机会重新显示的情况下才会去调用onSaveInstanceState(),而正常退出,被系统正常销毁的时候是不会调用该方法的。另外还原数据有两个地方可以进行还原,一个是在onCreate()中,在这里还原时,注意要判断savedInstanceState是否为空,另一个是在onRestoreInstanceState()回调中还原,而onRestoreInstanceState()方法一旦被调用,savedInstanceState肯定是有值的,所以不用在里面做判空处理。
- 资源内存不足导致低优先级的Activity被杀死
我们需要先知道Activity的优先级情况,如下所示:
(1)前台Activity。正在和用户交互的Activity,优先级最高。
(2)可见非前台Activity。如被Dialog遮挡的Activity,位于后台,无法和用户直接交互。
(3)后台Activity。如已经执行了onStop()回调的Activity,优先级最低。
当系统内存不足时,系统会按照以上优先级去先后杀死目标Activity所在的进程,并在后续中通过onSaveInstanceState()和onRestoreInstanceState()来存储和恢复数据。如果一个进程中没有四大组件在执行,那么这个进程很快就会被系统杀死,因此一些后台工作会放到Service中从而保证有一定的优先级,这样就不会被系统轻易的杀死。
使Activity不被重建的方法
最简单的,就是给标签内指定configChanges属性,比如不想让Activity旋转的时候重建,就添加如下属性:
android:configChanges="orientation"
如果我们想指定多个值,可以使用“|”号连接,比如这样:
android:configChanges="orientation|keyboardHidden"
还有其他配置值,具体使用可参考下图:
上面的值很多,但实际上我们在使用时,最常用的只有local、orientation和keyboardHidden这三个选项。还有注意screenSize和smallestScreenSize这两个选项,它们和编译选项有关和运行环境无关。比如:当编译环境targetSdkVersion和minSdkVersion有一个大于13时,可以这么写:
android:configChanges="orientation|screenSize
以上就是Activity的生命周期介绍,下一篇我将记录书中讲到的《Activity的启动模式》。