个人笔记
Android — Activity常见问题
Android 提供与用户进行交互的可视化页面容器
一.生命周期
- onCreate() —— 创建
- onStart() —— 启动 可见
- onResume() —— 恢复 可交互
- onPause() —— 暂停 不可交互
- onStop() —— 停止 不可见
- onDestroy() —— 销毁
生命周期常见问题
- Activity从创建到销毁生命周期调用顺序
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestroy()
- 从A Activity 跳转 B Activity 生命周期的调用
A onPause() -> B onCreate() -> B onStart() -> B onResume() -> A onStop()
- 接2 从 B 回退到 A 生命周期的调用
B onPause() -> A onStart() -> A onResume() -> B onStop() -> B onDestroy()
- 接2 如果A 跳转 B 时,调用 finish() 生命周期的调用
A onPause() -> B onCreate() -> B onStart() -> B onResume() -> A onStop() -> A onDestroy()
- 接4 如果此时 从 B Activity 回退 会发生什么 生命周期的调用 回退时会直接退出应用
B onPause() -> B onStop() -> B onDestroy()
二.启动模式
- Standard 标准模式
- Activity的默认启动模式
- Activity启动时系统都会创建一个对应实例,并置入当前任务栈中
- 无论是否存在相同实例,都将创建一个新的实例,因此一个栈中可能有多个相同实例
- SingeleTop 栈顶复用模式
- 该模式下启动Activity时,若当前任务栈栈顶存在该Activity的实例,则复用该实例
- 若当前任务栈中不存在该实例或实例不在栈顶时,系统会创建一个新的实例置入任务栈中
- 使用方式
- 在
AndroidManifest文件中指定launchMode
<activity android:name=".MainActivity" android:launchMode="singleTop"/>- 在Java代码中设置
Intent标志位指定 优先级高于Manifest文件指定
Intent intent = new Intent(MainActivity.this, SecondActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - SingleTask 栈内复用模式
- 该模式下启动Activity时,若当前栈中存在该Activity实例时,则复用该实例
- 同时,复用该实例时,会将在它之上的所有Activity实例全部出栈
- 会进行任务栈匹配,通过
taskAffinity属性来指定任务栈,默认为程序包名- 若任务栈不存在,将新建任务栈并将Activity实例置入
- 若任务栈存在,则判断是否存在Acitvity实例,存在则调用
onNewIntent()复用,不存在则新建实例
- 使用方式
- 在
AndroidManifest文件中指定launchMode
<activity android:name=".MainActivity" android:launchMode="singleTask" android:taskAffinity="com.worriesl.launch"/>- 在Java代码中设置
Intent标志位指定 优先级高于Manifest文件指定
Intent intent = new Intent(MainActivity.this, SecondActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - SingleInstances 单实例模式
- 该模式下启动Activity时,首先查找系统中是否存在该实例
- 存在,则调用
onNewIntent()复用该实例 - 不存在,则新建一个任务栈,并创建一个新的Activity实例置入栈中
- 存在,则调用
- 使用方式
- 在
AndroidManifest文件中指定launchMode
<activity android:name=".MainActivity" android:launchMode="singleInstances" android:taskAffinity="com.worriesl.launch"/> - 该模式下启动Activity时,首先查找系统中是否存在该实例
三.Activity 状态
onSaveInstanceState()
onSaveInstanceState()用于保存一些临时的状态,通常在Activity停止时调用该方法,但仅限于系统停止Activity时,如按下Home键回到首页、内存不足回收Activity等,像通过回退键、finish()等主动销毁Activity时,不会调用该方法
onSaveInstanceState() 中将需要保存的状态以键值对的形式保存在Bundle对象中
该方法的调用时机在 API < 28 之前,通常是在onPause()后 onStop()前
而在 API >= 28之后,调用时机在onStop()之后
onRestoreInstanceState()
onRestoreInstanceState()用于在重建被销毁的Activity时,恢复在onSaveInstanceState()保存的数据
但并不是所有情况下都会调用onRestoreInstanceState(),像按下Home键,按下锁屏键等情况下不会调用该方法,而像屏幕旋转、系统回收Activity,重建时则会调用该方法
同时在onCreate()中同样可以获取到onSaveInstanceState()中保存的Bundle,所以也可以在onCreate()中恢复保存数据,但需要对Bundle进行判空,因为不调用onSaveInstanceState()时,Bundle为空
onRestoreInstanceState()调用时机在onStart()之后
onConfigurationChanged()
上面提到,当屏幕旋转时,会分别调用onSaveInstanceState() 和 onRestoreInstanceState() 进行保存和恢复数据
但当在Manifest文件中设置
android:configChanges="orientation|screenSize"
恢复数据时则不会调用onRestoreInstanceState()而是调用onConfigurationChanged()
android:configChanges还支持系统字体大小、地区、外接键盘等变化时的监听