典型情况下的生命周期
7个生命周期
onCreate :Activity 正在被创建
- 初始化布局和数据
onRestart :Activity 正在重新启动,从不可见变为可见状态
- 从 Home 或者新 Activity 返回旧 Activity
onStart :Activity 正在被启动,已经显示出来,但是没有出现在前台
- 无法和用户交互
onResume :Activity 已经可见了,显示到前台
- 可以交互
onPause :Activity 正在被停止
- 可以做存储数据、停止动画等操作
- 但不能做耗时操作,因为 onPause 执行完才会执行新 Activity 的 onResume
onStop :Activity 即将停止
- 可以做稍微重量级的回收
- 但同样不能太耗时 ?why
onDestroy :Activity 即将被销毁
- 回收和最终的资源释放
一些特殊情况
1.A 中启动 B,如果 B 是透明主题,A 的 onStop 不会被调用 ???
2.从 B 中返回 A,A 的生命周期:onRestart -> onStart -> onResume
3.onStart 和 onStop 在该 Activity 是否在可见时回调;
而 onResume 和 onPause 则在 Activity 是否在前台时回调。
注:
“可见”只是说显示,但不一定是用户可以看到、交互;
“前台”就是看得见、摸得着。
4.如何实现点击返回键,Activity 的 onDestroy 不被执行?
在所在的 Activity 中重写 onKeyDown() 方法,拦截返回事件,然后调用 moveTaskToBack() 方法:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK){
moveTaskToBack(true); //将当前 Activity 的 Task 放到 Activity 栈的后边
return false;
}
return super.onKeyDown(keyCode, event);
}
5.Activity 的启动流程简述:
- Instrumentation 处理启动 Activity 的请求,然后通过 Binder 将请求发给 AMS
- AMS 维护着一个 ActivityStack 并负责栈中 Activity 的状态管理
- AMS 通过 ActivityThread 去同步 Activity 的状态,从而完成生命周期的调用
Activity 的 Task 和 栈的概念?
异常情况下的生命周期
系统回收或者当前设备 Configuration 改变导致 Activity 被销毁重建的情况。
异常状态保存/恢复方法
在系统配置发生改变时,默认情况下 Activity 会被销毁重建。
异常终止的情况下会调用 onSaveInstanceState() 方法,重新创建后会调用 onRestoreInstanceState():
- 状态保存调用顺序:onPause -> onSaveInstanceState -> onStop
- 状态恢复调用顺序:onStart -> onRestoreInstanceState - >onResume
- 数据通过键值对的形式保存到 Bundle 中
数据恢复在 onCreate 或者 onRestoreInstanceState 中进行都可以,但是官方文件建议在
onRestoreInstanceState 中,因为它被调用时 bundle 一定是有值的,不需要判断。
系统自动做的保存/恢复工作
在 Activity 的异常情况下,系统会这两个保存、恢复方法中为我们做一定的工作,比如保存当前 Activity 的视图结构(View 的状态)。
Activity 异常终止时,系统保存 View 状态的流程简述:
- Activity 调用 onSaveInstanceState 保存数据
- 然后 Activity 委托 Window 保存数据
- Window 再委托上面的顶级容器保存数据
顶级容器(一般来说是 DecorView)再一一通知它的子元素保存数据
委托思想:上层委托下层去处理一件事。
比如这里的数据恢复,还有 View 的绘制过程、事件分发等。
系统内存不足时,优先杀死低优先级的 Activity
Activity 的三种优先级,从高到低顺序:
前台 Activity
- 正在和用户交互
- 优先级最高,最不可能被回收
可见但非前台
- 比如弹出 Dialog 的 Activity
后台 Activity
- 已经暂停,执行了 onStop
- 优先级最低
四大组件的优先级都比较高,因此后台想执行耗时工作时,需要依赖四大组件来保活。
比如讲后台工作放到 Service 中。
指定在某些配置改变时 Activity 不重建
我们可以在 AndroidManifest.xml 中配置 android:configChanges 来指定该 Activity 在哪些系统配置改变时不重新建立。
配置项很多,常用的是这四个:
android:configChanges="screenSize|orientation|keyboardHidden|locale"
- screenSize|orientation 指的是在屏幕旋转和尺寸改变时不重新创建
- keyboardHidden 指的是可用键盘的改变
- locale 指的是系统语言切换
注意:
从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。
因此,在开发针对 API 级别 13 或更高版本(正如 minSdkVersion 和 targetSdkVersion
属性中所声明)的应用时,若要避免由于设备方向改变而导致运行时重启,则除了 “orientation” 值以外,您还必须添加
“screenSize” 值。
现在,当其中一个配置发生变化时,Activity 不会重启。相反,Activity 会调用 onConfigurationChanged()方法,并且向此方法传递 Configuration 对象,这个对象代表当前所有配置,你可以根据不同配置进行不同的处理:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
如果在配置改变时仍使用旧的状态,则可以不实现 onConfigurationChanged()。
喜欢的话请帮忙转发一下能让更多有需要的人看到吧,有些技术上的问题大家可以多探讨一下。
![](https://img.haomeiwen.com/i15233518/0bcab281aa09b967.jpg)
![](https://img.haomeiwen.com/i15233518/0c89459ecc166133.png)
网友评论