Android 进阶1:Activity 的生命周期

《Android 开发艺术探索》去年就看完了,但由于当时水平不够,加上自己脑子愚笨,很多知识没有完全消化。还是再来回顾、敲敲、总结一遍吧。

典型情况下的生命周期

7个生命周期

  1. onCreate :Activity 正在被创建
    • 初始化布局和数据
  2. onRestart :Activity 正在重新启动,从不可见变为可见状态
    • 从 Home 或者新 Activity 返回旧 Activity
  3. onStart :Activity 正在被启动,已经显示出来,但是没有出现在前台
    • 无法和用户交互
  4. onResume :Activity 已经可见了,显示到前台
    • 可以交互
  5. onPause :Activity 正在被停止
    • 可以做存储数据、停止动画等操作
    • 但不能做耗时操作,因为 onPause 执行完才会执行新 Activity 的 onResume
  6. onStop :Activity 即将停止
    • 可以做稍微重量级的回收
    • 但同样不能太耗时 ?why
  7. 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 的三种优先级,从高到低顺序:

  1. 前台 Activity
    • 正在和用户交互
    • 优先级最高,最不可能被回收
  2. 可见但非前台
    • 比如弹出 Dialog 的 Activity
  3. 后台 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()

Thanks

《Android 开发艺术探索》 https://developer.android.com/guide/topics/resources/runtime-changes.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android先生

(新瓶旧酒)谷歌官方MVP项目学习--浅入源码

项目的目的是通过展示各种架构app的不同方式来帮助开发者解决架构问题。项目中通过不同的架构概念及方式实现了功能相同的app。你可以用示例来当做参考,或是干脆拿来...

901
来自专栏Youngxj

安卓的四大组件之Activity-活动

1585
来自专栏猿湿Xoong

Android 8.0 SystemUI(四):二说顶部 StatusBar

大家好,我是ptt,本篇是 SystemUI 的第四篇,也是 StatusBar 的第二说。

4954
来自专栏向治洪

android 网络通信框架volly

1. 什么是Volley 在这之前,我们在程序中需要和网络通信的时候,大体使用的东西莫过于AsyncTaskLoader,HttpURLConnection...

1885
来自专栏向治洪

android程序崩溃后重启

有时候由于测试不充分或者程序潜在的问题而导致程序异常崩溃,这个是令人无法接受的,在android中怎样捕获程序的异常崩溃,然后进行一些必要的处理或重新启动 ...

2707
来自专栏yang0range

Activity详解(二)——异常情况下的生命周期分析

最近 无意当中看到一道面试题是关于Activity异常情况下的生命周期分析,感觉自己还有所欠缺,随即在书中寻找完整答案,特记录如下。

1404
来自专栏青玉伏案

Android开发之Activity的生命周期以及加载模式

本篇博客就来好好的搞一下Activity的生命周期,如果搞过iOS的小伙伴的话,Activity的生命周期和iOS中ViewController的生命周期非常类...

2027
来自专栏图像识别与深度学习

《Android》Lesson02-第1个Project,Log

18612
来自专栏向治洪

安全退出app,activoty栈管理

前言 由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文。(之前看小强也写过一篇,这...

28210
来自专栏程序员互动联盟

【Android基础】Activity的生命周期函数

前言: 上一篇文章写了关于Activity生命周期和生命周期状态的介绍,这一篇文章给大家聊聊Activity生命周期函数。 主Activity: 应用程序的入口...

3224

扫码关注云+社区