Activity的生命周期


作为 Android 的四大组件( Activity ,Service ,BroadcastReceiver ,ContentProvider )之一,Activity 在 Android 中的地位是极其重要的,它主要负责软件界面的展示,是整个 APP 的门面,是直接与用户进行交互的部分,所以了解 Activity 的生命周期,可以使我们对它的使用更加游刃有余。

Activity 的生命周期

总的来说,Activity 的生命周期主要有以下七个:

  • onCreate:表示 Activity 正在被创建,这是生命周期的第一个方法。在这个方法中,我们可以做一些初始化工作,比如调用 setContentView 去加载界面布局资源、初始化 Activity 所需数据等。
  • onRestart:表示 Activity 正在重新启动。一般情况下,当当前 Activity 从不可见重新变为可见状态时,onRestart 就会被调用。这种情形一般是用户行为所导致的,比如用户按 Home 键切换到桌面或者用户打开了一个新的 Activity,这时当前的 Activity 就会暂停,也就是 onPause 和 onStop 被执行了,接着用户又回到了这个 Activity,就会出现这种情况。
  • onStart:表示 Activity 正在被启动,即将开始,这时 Activity 已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为 Activity 已经显示出来了,但是我们还看不到。
  • onResume:表示 Activity 已经可见了,并且出现在前台并开始活动。要注意这个和 onStart 的对比,onStart 和 onResume 都表示 Activity 已经可见,但是 onStart 的时候 Activity 还在后台,onResume 的时候 Activity 才显示到前台。
  • onPause:表示 Activity 正在停止,正常情况下,紧接着 onStop 就会被调用。在特殊情况下,如果这个时候快速地再回到当前 Activity,那么 onResume 会被调用。但是这种情况属于极端情况,用户操作很难重现这一场景。此时可以做一些存储数据、停止动画等工作,但是注意不能太耗时,因为这会影响到新 Activity 的显示,onPause 必须先执行完,新 Activity 的 onResume 才会执行。
  • onStop:表示 Activity 即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。
  • onDestroy:表示 Activity 即将被销毁,这是 Activity 生命周期中的最后一个回调,在这里,我们可以做一些回收工作和最终的资源释放。

这些生命周期的具体执行过程,我们可以用下面这幅图来表示:

img

特殊情况

我们上面所说的,是 Activity 一般情况下的生命周期,但有没有特殊情况会导致 Activity 的生命周期与一般情况下的不同呢,答案是有的,但是其主要步骤和上述一般情况是一样的,只不过多了两步: onSaveInstanceStateonRestoreInstanceState,当 Activity 不是由我们主动 finish, 而是因为内存不足被系统杀死或其他异常情况时,就会多这两步:

onSaveInstanceState 一般在 onStop 之前调用,它主要进行 Activity 状态和数据的存储。

onRestoreInstanceState 一般在 onStart 之后调用,它将 Activity 退出时存储的数据进行恢复。

在一般情况下,onSaveInstanceState 和 onRestoreInstanceState 是不会被 Activity 调用的。

实践

实践是检验真理的唯一标准,通过自己动手,得到的知识会更加牢固,所以下面通过两个 Activity 观察一下它们的生命周期。

我们新建一个 Activity,其界面内容就是 Androidstudio 自动生成的 HelloWorld ,再为 HelloWorld 添加一个点击事件用于退出界面,为了方便观察,我们用 Logcat 的 error 等级输出日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class MainActivity : AppCompatActivity() {

val TAG = this.javaClass.name

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hello_world.setOnClickListener {
finish()
}
Log.e(TAG, "onCreate")
}

override fun onStart() {
super.onStart()
Log.e(TAG, "onStart")
}

override fun onResume() {
super.onResume()
Log.e(TAG, "onResume")
}

override fun onRestart() {
super.onRestart()
Log.e(TAG, "onRestart")
}

override fun onPause() {
super.onPause()
Log.e(TAG, "onPause")
}

override fun onStop() {
super.onStop()
Log.e(TAG, "onStop")
}

override fun onDestroy() {
super.onDestroy()
Log.e(TAG, "onDestroy")
}
}

我们运行程序并点击 HelloWorld,可以在日志中看到如下信息。

1
2
3
4
5
6
2020-08-13 15:12:07.131 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onCreate
2020-08-13 15:12:07.138 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onStart
2020-08-13 15:12:07.140 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onResume
2020-08-13 15:12:23.509 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onPause
2020-08-13 15:12:23.871 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onStop
2020-08-13 15:12:23.875 12133-12133/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onDestroy

这和我们上面所描述的是一样的,我们再来模拟一下异常情况,在代码里添加异常情况的两个方法并添加一个 EditText (EditText 要有ID,否则不会保存其中的内容)。

1
2
3
4
5
6
7
8
9
 override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Log.e(TAG, "onSaveInstanceState")
}
//注意 activity 中有两个函数名称一样的方法,这里是只有一个参数的
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
Log.e(TAG, "onRestoreInstanceState")
}

我们打开屏幕旋转然后进入界旋,在 EditText 中 输入文字并旋转屏幕,可以在日志中看到下面的信息。

1
2
3
4
5
6
7
8
2020-08-13 15:31:32.962 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onPause
2020-08-13 15:31:32.964 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onStop
2020-08-13 15:31:32.967 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onSaveInstanceState
2020-08-13 15:31:32.969 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onDestro
2020-08-13 15:31:33.054 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onCreate
2020-08-13 15:31:33.058 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onStart
2020-08-13 15:31:33.063 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onRestoreInstanceState
2020-08-13 15:31:33.065 15658-15658/com.cpw.learningapplication E/com.cpw.learningapplication.MainActivity: onResume