ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
### 1.1 Activity生命周期全面分析 * 典型情况下生命周期:是指在有用户参与的情况下,Activity所经过的生命周期的改变 * 异常情况下的生命周期:指Activity被系统回收或者由于当前设备的配置发生改变从而导致Activity被销毁重建。 #### 1.1.1 典型情况下生命周期分析 生命周期的7个方法 * (1)**onCreate**:表示**Activity正在被创建**,这是生命周期的第一个方法。在这个方法中,我们可以**做一些初始化工作**,比如调用setContentView 去加载界面布局资源、初始化Activity 所需数据等。 * (2) **onRestart**:表示Activity 正在重新启动。**一般情况下,当当前Activity 从不可见重新变为可见状态时,onRestart就会被调用**。这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity 就会暂停,也就是onPause 和on Stop 被执行了,接着用户又问到了这个Activity,就会出现这种情况。 * (3)**onStart**:表示Activity 正在被启动,即将开始,这时**Activity 已经可见了,但是还没出现在前台,还无法和用户交互**。这个时候其实可以理解为**Activity已经显示出来了,但是我们还看不到。 可见,不可交互,并没有出现在前台。** * (4)**onResume**:表示Activity 已经**可见了,并且出现在前台并开始活动**。要注意这个和onStart 的对比, onStart 和onResume 都表示Activity已经可见,但是onStart 的时候Activity还在后台, onResume 的时候Activity 才显示到前台。 * (5) **onPause** :表示Activity 正在停止, 正常情况下,紧接着onStop 就会被调用。在特殊情况下,如果这个时候快速地再回到当前Activity , 那么onResume 会被调用。笔者的理解是,这种情况属于极端情况,用户操作很难重现这一场景。此时可以做一些存储数据、停止动画等工作,但是**注意不能太耗时,因为这会影响到新Activity 的显示, onPause 必须先执行完,新Activity的onResume才会执行。可见,但不可交互。** * (6)**onStop** :表示Activity即将停止,**可以做一些稍微重量级的回收工作,同样不能太耗时**。 * (7)**onDestroy**:表示Activity即将被销毁,这是Activity生命周期中的最后一个回调,在这里,我们可以**做一些回收工作和最终的资源释放。** Activity生命周期的切换过程 ![](https://box.kancloud.cn/f24f8b47d23148d4026bc274da950c11_710x856.png) * (1)Activity第一次启动:onCreate->onStart->onResume。 * (2)一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart方法就会被调用。 * (3)当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause -> onStop,但是如果新Activity采用了透明主题,那么onStop方法不会被回调。当用户再次回到原来的Activity时,回调如下:onRestart -> onStart -> onResume。 * (4) 用户退出Activity,onPause->onStop->onDestroy。 * (5)当Activity 被系统回收后再次打开,生命周期方法向调过程和(1) 一样,注意只是生命周期方法一样,不代表所有过程都一样 * (6) * 从整个生命周期来说, onCreate 和onDestroy 是配对的,分别标识着Activity的创建和销毁,井且只可能有一次调用。 * 从Activity是否可见来况, onStart 和onStop 是配对的,随着用户的操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次 * 从Activity 是否在前台来说, onResume 和onPause 是配对的,随着用户操作或者设备屏幕的点亮和熄灭,这两个方法可能被调用多次。 * (7)onStart和onStop对应,它们是从Activity是否可见这个角度来回调的;onPause和onResume方法对应,它们是从Activity是否位于前台这个角度来回调的。 * (8)从Activity A进入到Activity B,回调顺序是onPause(A) -> onCreate(B) -> onStart(B) -> onResume(B) -> onStop(A),所以不能在onPause方法中做重量级的操作,因为必须onPause执行完成之后新Activity才能Resume * (9)onStart开始到onStop之前,Activity可见。onResume到onPause之前,Activity可以接受用户交互。 * (10)在新Activity启动之前,栈顶的Activity需要先onPause后,新Activity才能启动。所以不能在onPause执行耗时操作。onStop中也不可以太耗时,资源回收和释放可以放在onDestroy中。 * (11)Activity 的启动过程的源码相当复杂,涉及Instrumentation、ActivityThread和ActivityManagerService(下面简称AMS )。简单理解,启动Activity的请求会由Instrumentation 来处理,然后它通过Binder向AMS发请求,AMS内部维护着一个ActivityStack并负责栈内的Activity的状态同步,AMS通过ActivityThread去同步 Activity的状态从而完成生命周期方法的调用 #### 1.1.2 异常情况下生命周期分析 **1、资源相关的系统配置发生改变导致Activity被杀死并重新创建** 例如Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生了改变,Activity就会被销 毁并重新创建。 ![](https://box.kancloud.cn/d4a54ccd8d625b41bf2d9ca2e6bd6b7c_524x330.png) 1. onSaveInstanceState方法只会出现在Activity被异常终止的情况下被调用,它的调用时机是在onStop之前,它和onPause方法没有既定的时序关系,可能在它之前,也可能在它之后。 2. 当Activity被重新创建的时候,onRestoreInstanceState会被回调,它的调用时机是onStart之后。 当Activity被重新创建的后系统会调用onRestoreInstanceState和onCreate方法来判断Activity是否被重建了;如果被重建了,可以取出之前保存的数据并恢复。 3. 系统只会在Activity即将被销毁并且有机会重新显示的情况下才会去调用onSaveInstanceState方法。 4. onSaveInstanceState方法和onRestoreInstanceState方法中,系统自动为我们做一定的恢复工作。当Activity在异常情况下需要重新创建时,系统会默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、listview滚动的位置等,这些view相关的状态系统都会默认为我们恢复。具体针对某一个view系统能为我们恢复哪些数据可以查看view的源码中的onSaveInstanceState和onRestoreInstanceState方法。 5. 关于保存和恢复View层次结构,系统的工作流程是:Activity被意外终止,调用onSaveIntanceState保存数据-> Activity委托Window,Window委托它上面的顶级容器一个ViewGroup( 可能是DecorView) 。然后顶层容器在通知所有子元素来保存数据。 **2、资源内存不足导致低优先级的Activity被杀死** **Activity按优先级的分类** (从高到低) 前台Activity:正在和用户交互的Activity,优先级最高 可见但非前台Activity:比如Activity中弹出一个对话框,导致Activity可见但是位于后台无法和用户直接交互 后台Activity:已经被暂停的Activity,比如执行了onStop,优先级最低 当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并在后续通过onSavelnstanceState 和onRestorelnstanceState 来存储和恢复数数据。**如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死**,因此,一些后台工作不适合脱离四大组件而独自运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。 (3)`android:configChanges="xxx"`属性,常用的主要有下面三个选项: **local**:设备的本地位置发生了变化,一般指切换了系统语言; **keyboardHidden**:键盘的可访问性发生了变化,比如用户调出了键盘; **orientation**:屏幕方向发生了变化,比如旋转了手机屏幕。 配置了android:configChanges="xxx"属性之后,Activity就不会在对应变化发生时重新创建,而是调用Activity的onConfigurationChanged方法。 下表是configChanges的项目和含义 ![](https://box.kancloud.cn/de3457b66bed06c2255a25b38832d062_921x699.png) >[info] 注意:screenSize和smallestScreenSize,这两个比较特殊,它们的行为和编译选项有关,但和运行环境无关