Activity生命周期
前言
因为工作需要把DialogFragment改写成Dialog,在开发过程中发现Dialog的生命周期只有寥寥几个,也想起来自己对生命周期也只是停留在他大概是做什么用的阶段,所以写下这边文章梳理一下。
按照官网对生命周期的描述,大致可以理解成为Activity类提供了六个核心回调用于Activity各个阶段状态之间的转换,当Activity进入新的状态时,系统会调用其中与之对应的生命周期回调
生命周期的状态
Activity的创建会经历一系列的初始化,如官网所描述的onCreate会在系统首次创建Activity时触发回调,但是在这之前其状态会被设置成ON_CREATE从而进入“已创建”状态,我们在界面切换的时候,Activity也会在多种状态之间切换与之对应的就是回调相应的生命周期方法。可以重写这些生命周期方法实现对应的逻辑。
状态一共有9种他定义在ActivityLifecycleItem抽象类中,是AMS管理Activity生命周期的事务类,我们主要关注的是其中六个看名称也知道与之对应的生命周期方法了。
// Activity刚被创建时
public static final int ON_CREATE = 1;
// 执行完转到前台的最后准备工作
public static final int ON_START = 2;
// 执行完即将与用户交互的最后准备工作
// 此时该activity位于前台
public static final int ON_RESUME = 3;
// 用户离开,activity进入后台
public static final int ON_PAUSE = 4;
// activity不可见
public static final int ON_STOP = 5;
// 执行完被销毁前最后的准备工作
public static final int ON_DESTROY = 6;
状态之间的跳转是受到AMS管理,不能直接从ON_CREATE直接跳转到ON_PAUSE状态,状态切换就会回调对应生命周期方法如下图所示:
总结
生命周期的一个重要作用就是让Activity在不同状态之间切换的时候,可以执行对应的逻辑,在合适的生命周期做合适的工作会让程序变得更具有健壮性。从上图可以看出,生命周期的回调就发生在状态之间的切换过程中。了解生命周期的目的说白了就是让我们能够在不同的业务场景下做合适的工作。
1. 正常情况下的生命周期
先上一个参照官网生命周期画的中文版
1.1 一个正常的Activity经历的完整生命周期
1.1.1 onCreate
进入“已创建”状态,创建Activity必须实现的回调,在系统首次创建Activity时触发,这里可以基本的初始化工作初始化activity所需要的数据,例如系统默认的就会为我们调用setContentView去加载界面布局资源,如将Activity与viewModel关联起来等等,这个方法会接收一个savedInstanceState 参数,是一个bundle对象包含activity之前保存的状态,如果activity之前没有存在这个bunlde就是空的。
onCreate方法执行完后,Activity进入“已开始”状态,系统会相继调用onStart和onResume。
1.1.2 onRestart
一般表示当前Activity在重新启动,activity从不可见变为可见状态时,这个方法就会被调用,onRestart的启动时机通常容易被以下几种场景触发:
- 用户回到桌面或打开其他软件
- 打开新的Activity,然后在回到原来的
此时onPause和onStop会被触发执行,如果再回到这个Activity就会触发onRestart方法。
1.1.3 onStart
Activity进入“已开始”状态,系统会回调onStart方法,这个时候activity已经可见了,只是还在后台为进入前台做准备,所以看不见。通常在这个方法可以写一些维护界面的代码。
1.1.4 onResume
Activity进入“已恢复”状态,此时Activity已经在前台并且可见了,onStart和onResume相比,他们都表示Activity可见,但是一个在后台一个在前台。在这里可以做一些Activity位于前台时做的事情,比如启动相机。
1.1.5 onPause
Activity进入“已暂停”状态,表示Activity不在处于前台,然后会立即调用onStop,在这个方法里面不应该在做一些继续下去的操作,应该做一些轻量的不耗时的操作,如停止动画,数据存储等等,否则会影响新的Activity,onPasue执行完新Activity的onResume方法才会执行。
进入这个状态的原因有很多,以下是常见场景:
- 如我之前在上面onResume描述的场景场景
- 接电话,或在多窗口模式时会中断执行并触发该方法
- 在 Android 7.0(API 级别 24)或更高版本中,有多个应用在多窗口模式下运行。无论何时,都只有一个应用(窗口)可以拥有焦点,因此系统会暂停所有其他应用。
- 有新的半透明 Activity(例如对话框)处于开启状态。只要 Activity 仍然部分可见但并未处于焦点之中,它便会一直暂停。
1.1.6 onStop
Activity进入“已停止”状态,表示activity对用户不可见,系统会回调该方法,启动新的Activity覆盖整个屏幕时,可能会发生这种情况。
在这里可以做一些稍微重量级的回收工作,例如将精确位置更新切换到粗略位置更新或释放对用户不可见时的无用资源,切记也不能太耗时否则等着bug单改代码吧。
1.1.7 onDestroy
Activity进入“已销毁”状态,表示activity即将被销毁,在该回调方法应该释放掉在onStop方法内未释放的所有资源。
系统调用此回调的原因包括但不限于以下场景:
- Activity即将结束,用户彻底关闭此Activity或者由系统调用Activity的finish
- 由于横竖屏切换或多窗口模式,系统暂时销毁Activity
针对生命周期图可能有以下这些情况
Activity的第一次启动时,回调如下:onCreate->onStart->onResume,如果回到桌面或者打开新的activity会执行onPause->onStop,如果新的Activity是透明主题那么onStop不会回调。当我们再回到activity时会执行onRestart->onStart->onResume,按下back时会执行onPasue->onStop->onDestroy。如果要在用户返回桌面或退出时做一些什么重写onBackPressed即可。如果activity被系统回收然后在打开生命周期回调跟开头讲的一样,但是所有的过程不一定一样。
生命周期六个回调都是一一对应的如:
- onCreate - onDestroy,对应创建和销毁,可能只有一次调用(正常情况)
- onStart - onStop,对应开始和停止,从是否可见的角度来说他们是可见的,只是此时还位于后台没有在前台,会因为各种情况被调用很多次。
- onResume - onPause 对应恢复和暂停,从是否可见的角度来说他们是可见的,此时位于前台,也会因为各种情况被调用很多次
- onStart - onStop和onResume - onPause是差不多的,只是一个是从是否可见的角度和是否位于前台的角度来看,并且根据业务场景选择相应的回调,如自定义dialog时UI数据的初始化就适合放在onStart,在进入页面和回退页面时可以在onResume向服务端拉取数据。onPasue通常用的比较少(看业务场景吧),其次是onStop然后是onDestroy,一般的清理工作基本上都在onDestroy。
- onStart是后台与前台的区分,onResume区分的是否可交互,如在onResume中弹出一个popupWindow会有一个异常:token is null 表示界面还没有被添加到屏幕上,这种情况只出现在第一次启动Activity的时候,启动之后的activitydecorView就有token了所以弹出就不会有问题,所以要区分onResume被回调的时候是不是第一次创建。
2 其他生命周期方法
onActivityResult
这个是经常使用的,结合startActivityForResult一起用,通常用的比较多场景是调起相机并获取结果。
onSaveInstanceState和onRestoreInstanceState
在Activity被异常杀死的情况下存储和恢复界面数据,意外杀死的情况有很多种,如系统配置发生改变,内存不足时会杀死优先级比较低的Activity,当重新返回这个activity时希望界面的数据还在则需要在onSaveInstanceState方法中保存数据,这个方法只在被异常杀死时回调,activity重建之后可以在onRestoreInstanceState取出数据,onCreate也可以取出onSaveInstanceState保存的数据。
onRestoreInstanceState和onCreate的区别在于onCreate的数据可能为空而onRestoreInstanceState的数据一定不为空。
不同的Android版本调用onSaveInstanceState时机不同,api28之后onSaveInstanceState在onStop之后调用,api28之前调用在onStop之前调用。
总结
了解了Activity的状态以及对应的生命周期回调在不同场景下的使用方法以及一些其他小知识点和注意的点。虽然说的不够深入但是相比较之前还是有进步的,后期如果有相关零碎的笔记整理之后在补充上来。
参考
Android官网:了解 Activity 生命周期
Android全面解析之Activity生命周期
[Android开发艺术探索] 任玉刚