您当前的位置:首页 > Android教程

Android开发学习教程(23)- 浅谈Activity的生命周期

时间:2022-01-19 14:20:05 阅读数:17,921人阅读
版权声明:转载请注明出处,谢谢!
—— 一举成名天下知,十年寒窗满腹墨。

关于 Activity 的生命周期,可以说是每一位 Android 开发者的入门必备知识,也可以说是入了门就几乎不会再翻看的内容。

相信同行们都知道,这是初级开发者面试必问的问题,虽然问这个问题的意义并不大,主要还是面试官要找一个开场过渡一下罢了。

虽说简单,但是如果答不上来,那可不是出师未捷身先死?

先来放一张来自官方文档陈年经典老图:

下面一一介绍一下生命周期的七个函数调用:

onCreate() :当 Activity 第一次创建时会被调用。这是生命周期的第一个方法,在这个方法中,可以做一些初始化工作,比如调用 setContentView() 去加载界面布局资源,初始化 Activity 所需的数据。当然也可借助 onCreate() 方法中的 Bundle 对象来回复异常情况下 Activity 结束时的状态。

onRestart() :表示 Activity 正在重新启动。一般情况下,当当前 Activity 从不可见重新变为可见状态时,onRestart() 就会被调用。这种情形一般是用户行为导致的,比如用户按 HOME 键切换到桌面或打开了另一个新的 Activity,接着用户又回到了这个 Actvity。

onStart() :表示 Activity 正在被启动,即将开始,这时 Activity 已经出现了,但是还没有出现在前台,无法与用户交互。这个时候可以理解为 Activity 已经显示出来,但是我们还看不到。

onResume() :表示 Activity 已经可见了,且出现在前台并开始活动。需要和 onStart() 对比,onStart() 的时候 Activity 还在后台, onResume() 的时候 Activity 才显示到前台。

onPause() :表示 Activity 正在停止但仍可见,正常情况下,紧接着 onStop() 就会被调用。在特殊情况下,如果这个时候快速地回到当前 Activity,那么 onResume() 就会被调用(极端情况)。onPause() 中不能进行耗时操作,会影响到新 Activity 的显示。因为 onPause() 必须执行完,新的 Activity 的 onResume() 才会执行。

onStop() :表示 Activity 即将停止,不可见,位于后台。可以做稍微重量级的回收工作,同样不能太耗时。

onDestory() :表示 Activity 即将销毁,这是 Activity 生命周期的最后一个回调,可以做一些回收工作和最终的资源回收。

另一张来自《Android programming: the big nerd ranch guide》的图我觉得也能够很好地帮助理解:

这里说的是 Activity 的三种运行状态:

Resumed(活动状态):又叫 Running 状态,这个 Activity 正在屏幕上显示,并且有用户焦点。这个很好理解,就是用户正在操作的那个界面。

Paused(暂停状态):这是一个比较不常见的状态。这个 Activity 在屏幕上是可见的,但是并不是在屏幕最前端的那个 Activity。比如有另一个非全屏的或者透明的 Activity 是 Resumed 状态,没有完全遮盖这个 Activity。

Stopped(停止状态):当 Activity 完全不可见时,此时 Activity 还在后台运行,仍然在内存中保留 Activity 的状态,并不是完全销毁。这个也很好理解,当跳转的另外一个界面,之前的界面还在后台,按回退按钮还会恢复原来的状态,大部分软件在打开的时候,直接按 HOME 键,并不会关闭它,此时的 Activity 就是 Stopped 状态。

当然,有些文章也会把它描述成五种状态,并不影响理解:

只不过是把启动和销毁两种状态加进来罢了,实际上讨论这两种状态的意义并不大,可以作为参考。

综合之后,我们可以参考这张图:

接下来是关于生命周期在一些情况下的表现。

1. 正常情况下从一个 Activity 启动另一个 Activity,两个 Activity 的生命周期如何交替?

2. 按Home键/按显示最近任务键/锁屏/接到来电会执行哪些生命周期函数?

一般会执行 onPause() 和 onStop() 两个方法,但不绝对,也有部分机型并不会执行生命周期的任何方法。

3. 什么时候会仅执行 onPause() 而不执行 onStop()?

上面介绍 Activity 运行状态时也有提到,执行 onPause() 而不执行 onStop(),即 Activity 进入了 Paused 状态,此时比如有另一个非全屏的或者透明的 Activity 是 Resumed 状态,即在前台和用户交互,原来这个可见但不可交互的 Activity 就是处于 Paused 状态,不会执行到 onStop()。

4. 弹出 AlertDialog 后 Activity 会执行哪些生命周期函数?

并不会执行 Activity 的任何生命周期函数。

5. 长按POWER键/下拉状态栏会会执行哪些生命周期函数?

并不会执行 Activity 的任何生命周期函数。

6. 切换屏幕方向时会执行哪些生命周期函数?

在横竖屏切换的过程中,会发生 Activity 被销毁并重建的过程。虽然可以简单粗暴地描述成 Activity 经历了一次完整的生命周期后再次重建,但实际上要复杂些。

了解这种情况下的生命周期时,首先应该了解这两个回调:onSaveInstanceState() 和 onRestoreInstanceState()。

在 Activity 由于异常情况下终止时,系统会调用 onSaveInstanceState() 来保存当前 Activity 的状态。这个方法的调用是在 onDestroy() 之前,它和onPause() 没有既定的时序关系,该方法只在 Activity 被异常终止的情况下调用。

当异常终止的 Activity 被重建以后,系统会调用 onRestoreInstanceState(),并且把 Activity 销毁时 onSaveInstanceState() 方法所保存的 Bundle 对象参数同时传递给 onRestoreInstanceState() 和 onCreate() 方法,你可以很明显的看到,onCreate() 方法入参就有一个 Bundle 对象。

因此,可以通过 onRestoreInstanceState() 方法来恢复 Activity 的状态,该方法的调用时机是在 onStart() 之后。

其中 onCreate() 和 onRestoreInstanceState() 方法来恢复 Activity 的状态的区别:onRestoreInstanceState() 回调则表明其中 Bundle 对象非空,不用加非空判断,而 onCreate() 需要非空判断。建议使用 onRestoreInstanceState()。

7. 切换屏幕方向时 Activity 生命周期如下:

尽管官方文档中提到 onSaveInstanceState() 会调用在 onStop() 之前,并可能会调用在 onPause() 之前,但是我实际测试中发现,它在 Android 9.0 上也有可能会在 onStop() 之后才调用,我暂时找不到解释的理由,所以对于官方的说法,我暂时做一些修改,onSaveInstanceState() 会在 onDestroy() 之前调用,跟 onPause() 和 onStop() 没有既定的时序关系。

跟《第一行代码——Android》的作者郭霖交流过后得到的回复是,onSaveInstanceState() 方法不在 Activity 正常的生命周期之中,所以不同系统版本的表现都有可能不一样,只要知道其作用即可,不要依赖于执行的先后顺序去处理逻辑。

在开发中,常常会指定屏幕方向或禁用屏幕旋转

	<activity
		...
		android:screenOrientation="portrait" />
	或
	<activity
	...
	android:screenOrientation="nosensor" />

或者在 Activity 中指定以下属性来避免切换屏幕方向时 Activity 的销毁与重建:

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

指定该属性后,Activity 则会回调以下的方法:

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}

8. 分屏模式下会执行哪些生命周期函数?

同样会执行销毁及重建的过程

9. 当系统内存不足时,哪些 Activity 可能会被杀死?

当系统内存不足时,优先级低的 Activity 会被杀死,而 Activity 优先级的划分和 Activity 的三种运行状态也是对应的。

Resumed 状态的 Activity 优先级最高,它正在和用户交互。

Paused 状态的 Activity 优先级稍低,它虽然不能和用户交互,但它依然可见。

Stopped 状态的 Activity 优先级最低,它已完全不可见。

当系统内存不足时,会按照上述优先级从低到高去杀死目标 Activity 所在的进程。我们在平常使用手机时,能经常感受到这一现象。这种情况下数组存储和恢复过程和上述情况一致,生命周期情况也一样。

这里仅讨论 Activity 所在进程的优先级,其实该问题可以放大到应用进程中进行讨论,比如和 Service 的优先级比较等。

简单做一个总结,我是这样理解:凡是涉及到当前 Activity 的变动,才会触发生命周期的函数,而涉及到系统级的事件不会导致 Activity 的生命周期变化,需要注意的是,虽然弹出 AlertDialog 依赖于 Activity,但实际上也有系统级的 AlertDialog,所以我把 AlertDialog 归类于系统级事件。

该文大致回顾了 Android 中 Activity 的生命周期,它是每个 Android 开发者的基础知识,一定要掌握,掌握的目的,当然不是为了应付面试,而是为了在开发中更好的运用。

毕竟根基不牢,再高的建筑也会倒塌。

完整项目源码地址:https://github.com/heluicare/some-note

文章转载自 https://liarrdev.github.io/post/浅谈Activity的生命周期/

转载请注明出处,谢谢!

有偿提供技术支持、Bug修复、项目外包、毕业设计、大小作业

Android学习小站

Q Q:1095817610

微信:jx-helu

邮箱:1095817610@qq.com

添加请备注"Android学习小站"