2.Activity异常情况下的生命周期分析学习笔记

Activity除了受用户操作所导致的正常的生命周期方法调度,还有一些异常情况。
    比如:当资源相关的系统配置发生改变以及系统内存不足的时候,Activity就有可能被杀死。
情况可以分为下面2种。
2.1 资源相关的系统配置发生改变导致Activity被杀死并且创建。
    
    常见的情形比如:常见的手机屏幕旋转,或者外接入了显示屏、键盘等情况。
    例如,当前的手机目前是横屏状态,旋转了屏幕,这样导致了系统的配置发生了改变。默认情况下,Activity会经历一个销毁重建的过程,当然我们也可以阻止系统重新创建我们的Activity(可以在AndroidManifest.xml中指定Activity的configchanges)。默认情况下,当系统配置发生改变,Activity都会被销毁并且重新创建。
    问题:配置改变的时候处于后台的Activity会不会被销毁,是在什么时候销毁,和前台一致吗?
    配置改变了以后,Activity会调用onPause,onStop,onDestory,并且,因为是异常情况下终止,所以,系统会调用onSaveInstanceState来保存当前的Activity的状态。这个方法是在onStop之前调用的,但是和onPause的时序关系并不一定,可能在onPause前,也可能在onPause后。onSaveInstanceState只会出现在异常停止的情况下,正常的生命周期是不会调用的。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且会吧Activity销毁时onSaveInstanceState方法保存的Bundle对象作为参数传给onRestoreInstanceState和onCreate方法。onRestoreInstanceState调用在onStart之后。
    在onSaveInstanceState和onRestoreInstanceState中,系统自动为我们做了一些恢复和保存的工作吗,比如TextView的内容,EditText的输入文本、ListView滚动的位置、CheckBox的选中状态,这些和View相关的状态,系统会为我们保存和恢复。每个View都有onSaveInstanceState和onRestoreInstanceState。
    在保存和恢复View的时候,系统的工作流程大致如下:
    Activity异常关闭->调用Activity的onSaveInstanceState->Activity委托Window去保存数据->Window委托Window上面最顶层的Layout(ViewGroup类型,一般是DecorView)->顶层Layout再一一通知子元素来保存数据
    这是一种委托思想:上层委托下层,父容器委托子元素来处理这个流程。这个思想在事件分发、View绘制过程中都用到了。

2.2 资源内存不足导致低优先级的Activity被杀死
 
   数据保存和恢复和情况1是一样的,下面描述一下Activity的优先级情况,Activity按照优先级从高到低可以分为如下:
    2.2.1 前台Activity
                正在和用户交互的Activity,优先级最高。
     2.2.2 可见但是并非是前台的Activity
                比如当前Activity被弹了一个对话框,或者是顶层有一个透明的Activity
      2.2.3 后台Activity
                已经执行了onStop,用户不可见,已经被暂停了,优先级是最低的。
    当内存不足的时候,系统就会按照上述哟西安吉去杀死目标Activity所在的进程,并且后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。
    如果一个进程没有四大组件在执行,那么这个进程将会很快被系统杀死。因此,一些后台工作不适合脱离四大组件而独自运行在后台中,这样的话,进程会很容易被杀死,比较好的方法就是把后台的工作放在Service中保证进程有一定优先级,这样不会轻易被系统杀死(感觉这就是Android卡顿占内存的原因了)。

2.3 资源相关配置改变的时候阻止系统杀死Activity
   
     可以通过在AndroidManifest.xml文件中,配置configchanges来属性,来阻止,比如我们不希望在屏幕改变的时候重新创建,那么就可以在configchanges属性中添加orientation,
    如:
    android:configChanges="orientation"
    多个值之间用 | 来连结。
    这样子的话,在屏幕旋转的时候就会回调Activity的onConfigChanges方法。需要注意下,在API 13以上,需要用
    android:configChanges="orientation|screenSize"来防止旋转销毁Activity.
    
    需要记住以下几个configChanges的项目和含义。
    locale:设备的本地位置发生了改变,一般是指切换了系统的语言。
    screenLayout:屏幕布局发生了改变,比如使用了新的显示设备。
    fontScale:系统字体发生了改变,比如用户选择了一个新字号。
    uiMode:用户界面模式发生了改变,比如开启了夜间模式(API 8增加)
    orientation:屏幕方向发生了改变。
    screenSize:屏幕的尺寸信息发生了改变,和屏幕方向有关,这个选项和编译选项有关,当编译选项中的minSdkVersion和targetSdkVersion都低于13,这个选项不会导致Activity的重启,否则会导致Activity重启 (API 13新增加)。
     smallestScreenSize:屏幕的物理尺寸信息发生了改变,和屏幕方向无关,这个选项和编译选项有关,当编译选项中的minSdkVersion和targetSdkVersion都低于13,这个选项不会导致Activity的重启,否则会导致Activity重启 (API 13新增加)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章