Android基础 - 重温Activity生命周期

《Android开发艺术探索》买了好久了,将近有两年了,一直没有好好系统的看过,在浑浑噩噩的过日子,浪费好多时间;现在从头再来,坚持下去给自己一个希望。

典型的生命周期

7个生命周期方法

  1. onCreate:Activity正在被创建
    1. 初始化布局资源和数据
  2. onRestart:Activity正在重启启动,从不可见变为可见状态
    1. 按Home键返回桌面,再点击桌面图标返回App
    2. 启动新Activity后,再返回这个Activity
  3. onStart:Activity正在被启动,已经可见了,但不在前台
    1. 没有焦点无法交互
  4. onResume:Activity已经可见了,显示到前台
    1. 有焦点可以交互
  5. onPasue:Activity正在停止
    1. 可以做一些存储数据、停止动画等工作
    2. 不适合做耗时的任务,会影响到新Activity的onResume,必须先执行完onPasue才会执行新Activity的onResume(必须先执行完onPause,才会启动新的Activity,在onPause做耗时工作会延迟新Activity启动)。
  6. onStop:Activity即将停止
    1. 一些资源回收的工作,不能太耗时(??)
    2. 太耗时,会影响从新Activity返回旧Activity的时间,不能及时返回,需待旧Activity中的onStop执行完后,才能返回。
  7. onDestroy:Activity即将销毁

    1. 可以回收和释放资源工作

    注:
    “可见”只是说显示,但不一定是用户可以看到、交互;
    “前台”就是看得见、摸得着,摸摸有反应。

生命周期切换过程

  1. 启动新Activity
    1. onCreate -> onStart -> onResume
  2. 打开新Activity或按Home键返回桌面
    1. 正常情况:onPause -> onStop
    2. 新Activity为透明主题:onPause (onStop不执行)
  3. 再次回到Activity(桌面返回或者新Activity返回)
    1. 正常情况:onRestart -> onStart -> onResume
    2. 新Activity为透明主题:onResume
  4. 按返回back键返回时
    1. onPause -> onStop -> onDestroy

异常情况下的生命周期

资源相关的系统配置发生改变或者系统内存不足时,Activity会被杀死,异常终止。

生命周期及数据存储与恢复

横竖屏旋转切换属于系统配置发生改变的情况,默认情况下,不做任何处理,Activity会被销毁并重新创建,整个生命周期如下:

  1. 销毁过程:onPause -> onSaveInstanceState -> onStop -> onDestroy
  2. 重建过程:onCreate -> onStart -> onRestoreInstanceState -> onResume

onSaveInstanceState和onRestoreInstanceState 只有在Activity异常终止时才会被回调,用来存储和恢复数据,其他情况是不会被触发这个过程。

数据恢复在 onCreate 或者 onRestoreInstanceState 中进行都可以,但是官方文件建议在 onRestoreInstanceState 中,因为它被调用时 bundle 一定是有值的,不需要判断。

数据存储与恢复的工作流程

  • Activity意外终止,调用onSaveInstanceState去保存数据
  • 然后Activity委托Window保存数据
  • 接着Window在委托它顶级容器(ViewGroup)保存数据
  • 最后,顶级容器(ViewGroup)通知子view去保存数据。

    委托思想:上层委托下层,父容器委托子元素处理
    比如View绘制过程、事件分发都是类似的思想。

系统内存不足,优先级低的Activity会被杀死

  1. 前台Activity:可见可与用户进行交互的Activity,优先级最高
  2. 可见非前台Activity:可见但不能与用户进行交互,又位于后台的Activity,比如在Activity显示Dialog。优先级次之
  3. 后台Activity:不可见又无法交互的Activity,一般是执行了onStop方法,优先级最低。

指定系统属性配置,使Activity不销毁重建

实际开发中,很多情况并不希望系统配置改变后,Activity生命周期销毁又重建,比如视频横竖屏播放等等。
实现上面的需求,在可AndroidMainfest中指定Activity的configChanges属性值,如下:

<activity
            android:name=".MainActivity"
            android:configChanges="orientation|screenSize" />

给configChanges指定了上面的属性值,Activity在横竖屏旋转时,onSaveInstanceState和onRestoreInstanceState及其他周期方法均不会被回调,只会回调onConfigurationChanged,可在其做一些业务需求操作,如下:

  @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation==Configuration.ORIENTATION_PORTRAIT){
            Log.d(TAG, "竖屏业务逻辑……");
        }else if (newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){
            Log.d(TAG, "横屏业务逻辑……");
        }
    }

configChanges的属性值有很多,常见的如下:

  • orientation:屏幕方法发生改变,比如旋转手机屏幕
  • keyboardHidden:键盘发生了改变,比如用户调出了键盘或者关闭
  • locale:系统语言发生了改变。

Activity的一些特殊情况

按返回键,Activity不销毁(不执行onDestroy)

重写onKeyDown方法,监听返回键事件,最后调用moveTaskToBack方法,如下:

   @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //监听返回键按钮
        if (keyCode==KeyEvent.KEYCODE_BACK){
            //将当前Activity移到Activity栈后面
            moveTaskToBack(true);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

Activity的onTrimMemory方法

从字面可以看出与内存有联系,当用户按Home键或back键导致界面UI被隐藏了不可见了,此时可以调用onTrimMemory方法进行一些资源内存的释放。Android代码内存优化建议-OnTrimMemory优化

 @Override
    public void onTrimMemory(int level) {
        super.onTrimMemory(level);
    }

Activity的主题设置

 android:theme="@style/Theme.AppCompat.Dialog"

设置该主题后,Activity会以对话框的形式弹出,此时onStop方法不会被调用,旧Activity处于可见但非前台的状态(与透明主题一样的)。

android:theme="@android:style/Theme.Translucent"
或
android:theme="@android:style/Theme.Dialog"

设置上面类似的主题,在启动中可能会报java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. 解决方案

关于透明主题设置如下:

// 一、style 文件,注意一点parent需继承Theme.AppCompat下
<style name="TransparencyTheme" parent="AppTheme">
        <item name="android:windowBackground">@color/colorTransparency</item>
       <item name="android:windowIsTranslucent">true</item>
</style>

// 二、color颜色
<color name="colorTransparency">#00000000</color>

//三、AndroidMainfest引用

android:theme="@style/TransparencyTheme"

感谢

猜你喜欢

转载自blog.csdn.net/hzw2017/article/details/80850828