1.1 Activity的生命周期分析
1.1.1 典型情况下的生命周期分析
正常情况下,Activity有如下生命周期。
- onCreate:表示Activity正在被创建,这是生命周期的第一个方法,通常用来做一些初始化工作,比如调用setContentView,加载数据等。
- onRestart:表示Activity正在被重新启动,一般情况下是由于Activity从不可见重新变为可见时,onRestart会被调用。
- onStart:表示Activity正在被启动,即将开始,此时Activity已经可见,但是还没有出现在前台,无法与用户交互。这个时候可以理解为Activity已经显示出来了,但是我们看不到。
- onResume:表示Activity已经可见,并且出现在前台开始活动。
- onPause:表示Activity正在停止,正常情况下,紧接着onStop会被调用。此时可以做一些存储数据、停止执行动画等工作,但不能太耗时,因为会影响到新的Activity的显示,因为转场时onPause必须执行完,新的Activity的onResume才会执行
- onStop:表示Activity即将停止(Activity被完全遮挡),可以做一些轻量级的回收工作,同样不能太耗时
- onDestroy:表示Activity即将被销毁,可以做一些资源回收工作。
-
Activity官方生命周期示例图
-
具体情况下Activity生命周期切换过程
1)第一次启动:onCreate -> onStart -> onResume
2)当用户打开新的Activity或者切回到桌面时,onPause -> onStop,这里有一种特殊情况,如果该Activity是透明主题,不会回调onStop
3)当用户再次切回原Activity时,onRestart -> onStart -> onResume
4)当用户按下back键时,onPause -> onStop -> onDestroy
5)当Activity被系统回收后再次打开,生命周期方法回调过程同1,但只是生命周期方法一样,此外还多出现场保存方法,属于异常情况下Activity的生命周期处理 -
Activity1启动Activity2,两个Activity生命周期函数回调顺序
Activity1:onPause
Activity2:onCreate
Activity2:onStart
Activity2:onResume
Activity1:onStop -
Q:onStart和onResume,onPause和onStop从描述上看来差不多,对我们来说有什么实质的不同?
A:onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台来回调的,主要区分Activity可见和可交互的不同,使用中可以只保留一个。
1.1.2 异常情况下的生命周期分析
- 资源相关的系统配置发生改变导致的Activity被杀死并重新创建
例如,屏幕旋转时,activity的生命周期:
MainActivity@5c08997:onPause -> onStop -> onDestroy
MainActivity@cace036:onCreate -> onStart -> onResume
可见,原Activity被杀死,并创建了新的Activity,并且由于Activity是在异常情况下被终止,系统会调用onSaveInstanceState保存当前Activity的状态。当Activity被重新创建后,系统调用onRestoreInstanceState,并且把异常销毁时onSaveInstanceState保存的Bundle对象作为参数传递给onCreate和onRestoreInstanceState,onRestoreInstanceState的调用时机在onStart之后
在onSaveInstanceState和onRestoreInstanceState中,系统自动为我们做了一些恢复工作。在Activity异常情况下需要重新创建时,系统默认为我们保存当前Activity的视图状态,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据,ListView的滚动位置等,具体想知道哪些View具有自动恢复数据的能力,查看对应类的onSaveInstanceState和onRestoreInstanceState这两个方法即可,例如TextView.onSaveInstanceState
- 使用onSaveInstanceState和onRestoreInstanceState保存数据
当屏幕旋转时,生命周期函数回调顺序:class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var data = "" if (savedInstanceState != null) { data = savedInstanceState.getString("extra_data")?:"" } Log.d("west", "$this onCreate $data") } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString("extra_data", "test") Log.d("west", "$this onSaveInstanceState") } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) val data = savedInstanceState.getString("extra_data") Log.d("west", "$this onRestoreInstanceState $data") } }
myapplication.MainActivity@5b74796 onPause
myapplication.MainActivity@5b74796 onStop
myapplication.MainActivity@5b74796 onSaveInstanceState
myapplication.MainActivity@5b74796 onDestroy
myapplication.MainActivity@b3b2960 onCreate test
myapplication.MainActivity@b3b2960 onStart
myapplication.MainActivity@b3b2960 onRestoreInstanceState test
myapplication.MainActivity@b3b2960 onResume
Activity异常销毁时,调用onSaveInstanceState保存了data,重建后onCreate和onRestoreInstanceState都打印出了test,onRestoreInstanceState的调用时机在onStart之后
基于Android5.0系统的《Android艺术探索》中提到onSaveInstanceState在onStop之前调用,但我实际操作(Android 10/MUI 12)发现onSaveInstanceState在onStop之后调用的,具体原因还需要继续研究
-
资源内存不足导致低优先级的Activity被杀死
其数据存储和恢复过程和1完全一致。
分析Activity的优先级情况,优先级从高到低分别为:- 前台Activity —— 正在和用户交互的Activity,优先级最高
- 可见但非前台的Activity —— 被dialog挡住或被透明Activity挡住
- 后台Activity —— 已经被暂停的Activity,比如执行了onStop
当系统内存不足时,会按优先级从低到高去杀死目标Activity所在的进程,并执行onSaveInstanceState和onRestoreInstanceState。
-
系统配置发生改变时,如何不重新创建Activity
比如屏幕旋转时,不希望activity重建,在activity便签下加上:android:configChanges=“orientation|screenSize”<activity android:name=".MainActivity" android:configChanges="orientation|screenSize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
《android艺术探索》中提到在activity便签下加上android:configChanges=“orientation”,没有"screenSize",在android4.0以上不生效。
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.d("west", "onCreate") } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) Log.d("west", "onConfigurationChanged") } }
没加上android:configChanges,旋转屏幕后:
D/west: onCreate
D/west: onCreate
D/west: onCreate
加上android:configChanges后,旋转屏幕时:
D/west: onCreate
D/west: onConfigurationChanged
D/west: onConfigurationChanged,
可见,加上android:configChanges,旋转屏幕时,不会触发activity重建,只会触发配置改变回调
参考书目《android开发艺术探索》