您的位置:首页 > 其它

Activity的生命周期及异常情况分析

2016-12-21 16:09 225 查看
1.正常情况下的生命周期:

(1)onCreate:表示Activity正在被创建,在这个方法中可以做初始化操作,比如调用setContentView去加载布局资源、初始化Activity所需的数据。

(2)onRestart:表示Activity正在重新启动。当当前Activity从不可见重新变为可见状态时,onRestart就会被调用。这种情况一般是用户行为导致的,比如Home键切换到桌面打开了一个新的Activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行,然后用户又返回到了这个Activity,就会出现这种情况。

(3)onStart:表示Activity正在启动,即将开始,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候可以理解为Activity已经显示出来了,但是我们还看不到。

(4)onResume:表示Activity已经可见了,出现在前台并开始活动。和onStart对比,onStart和onResume都标识Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候Activity才显示到前台。

(5)onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。此时可以做一些存储数据、停止动画等工作,但注意不能太耗时,因为这会影响到新Activity的显示,onPause必须先执行完,新Activity的onResume才会执行。

(6)onStop:表示Activity即将停止,可以做一些稍微重量级的回收工作,同样不能太耗时。

(7)onDestory:表示Activity即将被销毁,我们可以做一些回收工作和最终的资源释放。

onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的,除了这种区别,在实际使用中没有其他明显区别。

2.异常情况下的生命周期分析:

2.1资源相关的系统配置发生改变导致Activity被杀死并重新创建

例如当前Activity处于竖屏状态,如果突然旋转屏幕,由于系统配置发生改变,在默认情况下,Activity就会被销毁并且重新创建,当然我们也可以阻止系统重新创建我们的Activity。

当系统配置发生改变后,Activity会销毁,其onPause、onStop、onDestory均会被调用,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity状态。这个方法是的调用时机是在onStop之前,它和onPause没有既定的时序关系,它既可在onPause之前调用,也可能在onPause之后调用。这个方法只会出现在Activity被异常终止的情况下,正常情况下系统不会回调这个方法。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveIntanceState方法保存的Bundle对象作为参数同事传递给onRestoreInstanceState和onCreate方法。因此我们可以通过onRestorteInstanceState和onCreate方法来判断Activity是否被重建,如果被重建,那么我们就可以取出之前保存的数据并恢复,从时序上来说,onRestoreInstanceState的调用时机在onStart之后。

在onSaveInstanceState和onRestoreInstanceState方法中,系统自动为我们做了一定的恢复工作。当Activiyty在异常情况下需要重建时,系统默认为我们保存当前Activity的视图结构,并且在Activity重启后为我们恢复这些数据,比如文本框中用户输入的数据、ListView滚动位置等,这些View相关的状态系统都能默认为我们恢复。和Activity一样,每个View都有onSaveInstanceState和onRestoreInstanceState这两个方法,看一下它们的具体实现,就能知道系统能够自动为每个View恢复哪些数据。

关于保存和恢复View层次结构,系统的工作流程是这样的,首先Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window在委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,一般来说它很可能是DecorView。最后顶层容器再去一一通知它的子元素去保存数据,这样整个数据保存过程就完成了。这是一种典型的委托思想,上层委托下层,父容器委托子元素去处理一件事情,这种思想在Android中有很多的应用,比如View的绘制过程、事件分发等都是采用类似的思想。至于数据恢复过程也是类似。

当Acivity被销毁并重建后,我们再去获取之前存储的数据,接收的位置可以选择onRestoreInstanceState和onCreate,二者的却别是:onRestoreInstanceState一旦被调用其参数Bundle saveInstanceState一定是有值的,我们不用额外的判断是否为空,但是onCeate不行,onCreate如果是正常启动的话其参数Bundle saveInstanceState为null,所以必须要额外判断。这两个方法我们选择任意一个都可以进行数据恢复,但官方文档的建议是采用onRestoreInstanceState恢复数据。

系统只会在Activity即将被销毁并且有机会重新显示的情况下才会调用onSaveInstanceState,Activity正常销毁时不会调用onSaveInstanceState,因为Activity不可能再次被显示。比如旋转屏幕造成的Actvivity异常销毁,这个时候Activity有机会再次立刻展示,所以系统要进行数据存储。

2.2资源内存不足导致低优先级的Activity被杀死

这种情况的数据存储和恢复过程和上面情况完全一致。

Activity优先级按照从高到低可以分为如下三种:

(1)前台Activity-正在和用户交互的Activity,优先级最高。

(2)可见但非前台-比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互。

(3)后台Activity-已经被暂停的Activity,比如执行了onStop,优先级最低。

当系统内存不足时,系统就会按照上述的优先级杀死目标Activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。如果一个进程没有四大组件在执行,那么这个进程将很快被系统杀死,因此,一些后台工作不适合脱离四大组件而独自运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。

如果不想让Acticity在屏幕旋转的时候重新创建就可以给configChanges属性添加orientation这个值,如果我们想指定多个指可以用“|”连接起来,比如android:configChanges=”orientation|keyboardHidden”

编译版本不同也有些不同,如果编译版本大于13,需要改为android:configChanges=”orientation|screenSize”

当Activity不重建时,并且也没有调用onSaveInstanceState和onRestoreInstanceState来存储和恢复数据,取而代之的是系统调用了Activity的onConfigurationChanged方法,这个时候我们就可以做一些自己的处理了。

以上都是本人阅读《Android开发艺术探索》从其中摘写做为笔记。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Acticity