管理 Activity 生命周期


通过实现回调方法管理 Activity 的生命周期对开发强大而又灵活的应用至关重要。 Activity 的生命周期会直接受到 Activity 与其他 Activity、其任务及返回栈的关联性的影响。

Activity 基本上以三种状态存在:

已继续
此 Activity 位于屏幕前台并具有用户焦点。(有时也将此状态称作“运行中”。)
已暂停
另一个 Activity 位于屏幕前台并具有用户焦点,但此 Activity 仍可见。也就是说,另一个 Activity 显示在此 Activity 上方,并且该 Activity 部分透明或未覆盖整个屏幕。 已暂停的 Activity 处于完全 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,并与窗口管理器保持连接),但在内存极度不足的情况下,可能会被系统终止。
已停止
该 Activity 被另一个 Activity 完全遮盖(该 Activity 目前位于“后台”)。 已停止的 Activity 同样仍处于 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,但与窗口管理器连接)。 不过,它对用户不再可见,在他处需要内存时可能会被系统终止。

如果 Activity 处于暂停或停止状态,系统可通过要求其结束(调用其 finish() 方法)或直接终止其进程,将其从内存中删除。(将其结束或终止后)再次打开 Activity 时,必须重建。


实现生命周期回调

当一个 Activity 转入和转出上述不同状态时,系统会通过各种回调方法向其发出通知。 所有回调方法都是挂钩,您可以在 Activity 状态发生变化时替代这些挂钩来执行相应操作。 以下框架 Activity 包括每一个基本生命周期方法:

 public class ExampleActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The activity is being created.
}
@Override
protected void onStart() {
super.onStart();
// The activity is about to become visible.
}
@Override
protected void onResume() {
super.onResume();
// The activity has become visible (it is now "resumed").
}
@Override
protected void onPause() {
super.onPause();
// Another activity is taking focus (this activity is about to be "paused").
}
@Override
protected void onStop() {
super.onStop();
// The activity is no longer visible (it is now "stopped")
}
@Override
protected void onDestroy() {
super.onDestroy();
// The activity is about to be destroyed.
}
}

这些方法共同定义 Activity 的整个生命周期。您可以通过实现这些方法监控 Activity 生命周期中的三个嵌套循环:

  • Activity 的整个生命周期发生在 onCreate() 调用与 onDestroy() 调用之间。您的 Activity 应在 onCreate() 中执行“全局”状态设置(例如定义布局),并释放 onDestroy() 中的所有其余资源。例如,如果您的 Activity 有一个在后台运行的线程,用于从网络上下载数据,它可能会在onCreate() 中创建该线程,然后在 onDestroy() 中停止该线程。
  • Activity 的可见生命周期发生在 onStart() 调用与 onStop() 调用之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。 例如,当一个新 Activity 启动,并且此 Activity 不再可见时,系统会调用 onStop()。您可以在调用这两个方法之间保留向用户显示 Activity 所需的资源。 例如,您可以在 onStart() 中注册一个 BroadcastReceiver 以监控影响 UI 的变化,并在用户无法再看到您显示的内容时在 onStop() 中将其取消注册。在 Activity 的整个生命周期,当 Activity 在对用户可见和隐藏两种状态中交替变化时,系统可能会多次调用 onStart() 和 onStop()

  • Activity 的前台生命周期发生在 onResume() 调用与 onPause() 调用之间。在这段时间,Activity 位于屏幕上的所有其他 Activity 之前,并具有用户输入焦点。 Activity 可频繁转入和转出前台—例如,当设备转入休眠状态或出现对话框时,系统会调用 onPause()。 由于此状态可能经常发生转变,因此这两个方法中应采用适度轻量级的代码,以避免因转变速度慢而让用户等待。


保存 Activity 状态

管理 Activity 生命周期的引言部分简要提及,当 Activity 暂停或停止时,Activity 的状态会得到保留。 确实如此,因为当 Activity 暂停或停止时,Activity 对象仍保留在内存中 — 有关其成员和当前状态的所有信息仍处于 Activity 状态。 因此,用户在 Activity 内所做的任何更改都会得到保留,这样一来,当 Activity 返回前台(当它“继续”)时,这些更改仍然存在。

不过,当系统为了恢复内存而销毁某项 Activity 时,Activity 对象也会被销毁,因此系统在继续 Activity 时根本无法让其状态保持完好,而是必须在用户返回Activity时重建 Activity 对象。但用户并不知道系统销毁 Activity 后又对其进行了重建,因此他们很可能认为 Activity 状态毫无变化。 在这种情况下,您可以实现另一个回调方法对有关 Activity 状态的信息进行保存,以确保有关 Activity 状态的重要信息得到保留:onSaveInstanceState()

系统会先调用 onSaveInstanceState(),然后再使 Activity 变得易于销毁。系统会向该方法传递一个 Bundle,您可以在其中使用 putString() 和putInt() 等方法以名称-值对形式保存有关 Activity 状态的信息。然后,如果系统终止您的应用进程,并且用户返回您的 Activity,则系统会重建该 Activity,并将 Bundle 同时传递给 onCreate() 和 onRestoreInstanceState()。您可以使用上述任一方法从 Bundle 提取您保存的状态并恢复该 Activity 状态。如果没有状态信息需要恢复,则传递给您的 Bundle 是空值(如果是首次创建该 Activity,就会出现这种情况)。

在两种情况下,Activity 重获用户焦点时可保持状态完好:系统在销毁 Activity 后重建 Activity,Activity 必须恢复之前保存的状态;系统停止 Activity 后继续执行 Activity,并且 Activity 状态保持完好。

注:无法保证系统会在销毁您的 Activity 前调用 onSaveInstanceState(),因为存在不需要保存状态的情况(例如用户使用“返回” 按钮离开您的 Activity 时,因为用户的行为是在显式关闭 Activity)。 如果系统调用 onSaveInstanceState(),它会在调用 onStop() 之前,并且可能会在调用onPause() 之前进行调用。

从MainActivity跳转到OneActivity执行的流程
05-22 06:36:41.243 8949-8949/? E/MainActivity: onPause
05-22 06:36:41.260 8949-8949/? E/OneActivity: onCreate
05-22 06:36:41.263 8949-8949/? E/OneActivity: onStart
05-22 06:36:41.263 8949-8949/? E/OneActivity: onResume
05-22 06:36:41.836 8949-8949/? E/MainActivity: onSaveInstanceState(Bundle outState)
05-22 06:36:41.836 8949-8949/? E/MainActivity: onStop 解释说明一下哦!
  
05-22 06:36:41.836 8949-8949/? E/MainActivity: onSaveInstanceState(Bundle outState) 在这里保存数据(例如:视频播放的进度,ListView当前的位置等等一些数据) outState.putXXX();
注:这个方法还会在内存不足,系统回收销毁Activity的时候会回调这个方法哦~!!上面说到了按Back返回键是不会执行这个方法的哈。记住!!

这个时候你想问?保存了我返回或者重新进入Activity的时候怎么获取这个数据呢? protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);   //经常写OnCreate里面,而这个参数估计好多人不知道怎么用,这个参数就是我们在onSaveInstanceState的时候保存的值,这时候你就可以获取数据了。   //先判断一下哦!
  if (savedInstanceState != null) {
    //保险起见,这里也可以判断下是非有值,防止空指针的出现
   savedInstanceState.getXX();
  }
}

//这里

    @Override
public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onCreate(savedInstanceState, persistentState);
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
} @Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
} @Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
} @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
} @Override
public void onRestoreInstanceState(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onRestoreInstanceState(savedInstanceState, persistentState);
}

注:由于无法保证系统会调用 onSaveInstanceState(),因此您只应利用它来记录 Activity 的瞬态(UI 的状态)—切勿使用它来存储持久性数据,而应使用 onPause() 在用户离开 Activity 后存储持久性数据(例如应保存到数据库的数据)。

处理配置变更

有些设备配置可能会在运行时发生变化(例如屏幕方向、键盘可用性及语言)。 发生此类变化时,Android 会重建运行中的 Activity(系统调用onDestroy(),然后立即调用 onCreate())。此行为旨在通过利用您提供的备用资源(例如适用于不同屏幕方向和屏幕尺寸的不同布局)自动重新加载您的应用来帮助它适应新配置。

如果您对 Activity 进行了适当设计,让它能够按以上所述处理屏幕方向变化带来的重启并恢复 Activity 状态,那么在遭遇 Activity 生命周期中的其他意外事件时,您的应用将具有更强的适应性。

正如上文所述,处理此类重启的最佳方法 是利用 onSaveInstanceState() 和 onRestoreInstanceState()(或 onCreate())保存并恢复 Activity 的状态。

如需了解有关运行时发生的配置变更以及应对方法的详细信息,请阅读处理运行时变更指南。

进入Activity第一次旋转屏幕的流程

05-22 07:32:19.149 18025-18025/com.example.administrator.myapplication E/MainActivity: onCreate
05-22 07:32:19.150 18025-18025/com.example.administrator.myapplication E/MainActivity: onStart
05-22 07:32:19.150 18025-18025/com.example.administrator.myapplication E/MainActivity: onResume05-22 07:32:30.914 18025-18025/com.example.administrator.myapplication E/MainActivity: onPause
05-22 07:32:30.914 18025-18025/com.example.administrator.myapplication E/MainActivity: onSaveInstanceState(Bundle outState)
05-22 07:32:30.914 18025-18025/com.example.administrator.myapplication E/MainActivity: onStop
05-22 07:32:30.914 18025-18025/com.example.administrator.myapplication E/MainActivity: onDestroy
05-22 07:32:30.989 18025-18025/com.example.administrator.myapplication E/MainActivity: onCreate
05-22 07:32:30.989 18025-18025/com.example.administrator.myapplication E/MainActivity:onCreate 打印值: 100 //直接就是获取的Bundle值
05-22 07:32:30.990 18025-18025/com.example.administrator.myapplication E/MainActivity: onStart
05-22 07:32:30.990 18025-18025/com.example.administrator.myapplication E/MainActivity: onRestoreInstanceState(Bundle savedInstanceState)
05-22 07:32:30.990 18025-18025/com.example.administrator.myapplication E/MainActivity: onResume 再次旋转屏幕的流程

05-22 07:36:49.832 18025-18025/com.example.administrator.myapplication E/MainActivity: onPause
 05-22 07:36:49.832 18025-18025/com.example.administrator.myapplication E/MainActivity: onSaveInstanceState(Bundle outState)
 05-22 07:36:49.832 18025-18025/com.example.administrator.myapplication E/MainActivity: onStop
 05-22 07:36:49.832 18025-18025/com.example.administrator.myapplication E/MainActivity: onDestroy
 05-22 07:36:49.873 18025-18025/com.example.administrator.myapplication E/MainActivity: onCreate
 05-22 07:36:49.873 18025-18025/com.example.administrator.myapplication E/MainActivity:onCreate 打印值: 100 //直接就是获取的Bundle值

05-22 07:36:49.873 18025-18025/com.example.administrator.myapplication E/MainActivity: onStart
 05-22 07:36:49.873 18025-18025/com.example.administrator.myapplication E/MainActivity: onRestoreInstanceState(Bundle savedInstanceState)
 05-22 07:36:49.873 18025-18025/com.example.administrator.myapplication E/MainActivity: onResume

协调 Activity

当一个 Activity 启动另一个 Activity 时,它们都会体验到生命周期转变。第一个 Activity 暂停并停止(但如果它在后台仍然可见,则不会停止)时,系统会创建另一个 Activity。 如果这些 Activity 共用保存到磁盘或其他地方的数据,必须了解的是,在创建第二个 Activity 前,第一个 Activity 不会完全停止。更确切地说,启动第二个 Activity 的过程与停止第一个 Activity 的过程存在重叠。

生命周期回调的顺序经过明确定义,当两个 Activity 位于同一进程,并且由一个 Activity 启动另一个 Activity 时,其定义尤其明确。 以下是当 Activity A 启动 Activity B 时一系列操作的发生顺序:

  1. Activity A 的 onPause() 方法执行。
  2. Activity B 的 onCreate()onStart() 和 onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
  3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

您可以利用这种可预测的生命周期回调顺序管理从一个 Activity 到另一个 Activity 的信息转变。 例如,如果您必须在第一个 Activity 停止时向数据库写入数据,以便下一个 Activity 能够读取该数据,则应在 onPause() 而不是 onStop() 执行期间向数据库写入数据。

总结:


  • 当系统认为一个Activity有可能被回收时,那么系统会调用它的onSaveInstanceState方法
  • 当一个被回收的Activity被重新打开的时候,系统会调用它的onRestoreInstanceState方法
  • 当Activity的系统配置发生改变后,如果它被重新启动,那么系统会通过onSaveInstanceState来保存数据,同时会通过onRestoreInstanceState来恢复数据

  • 创建与销毁 onCreate,onDestory()
  • 是否可见 onStart(),onStop()
  • 是否在前台 onResume(),onPause()

Android Activity生命周期详讲的更多相关文章

  1. Android Activity 生命周期详解

    学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段 ...

  2. xamarin Android activity生命周期详解

    学Xamarin我为什么要写这样一篇关于Android 的activity生命周期的文章 已经学Xamarin android有一段时间了,现在想起当初Xamarin也走了不少的弯路.当然Xamari ...

  3. Android关于Activity生命周期详解

    子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细研读几遍,以领悟到作者的思想精 ...

  4. Android之Activity生命周期详解

    Activity的生命周期方法: onCreate()--->onStart()--->onResume()--->onPause()--->onStop()--->on ...

  5. [转]: 两分钟彻底让你明白Android Activity生命周期(图文)!

    转自:http://blog.csdn.net/android_tutor/article/details/5772285 大家好,今天给大家详解一下Android中Activity的生命周期,我在前 ...

  6. Android——Activity生命周期(转)

    Activity生命周期   子曰:溫故而知新,可以為師矣.<論語> 学习技术也一样,对于技术文档或者经典的技术书籍来说,指望看一遍就完全掌握,那基本不大可能,所以我们需要经常回过头再仔细 ...

  7. Android Activity生命周期

    从android api文档摘抄出来的activity生命周期图如下: Activity有如下四种状态 a.活动状态  activity处于屏幕前台,获取到了焦点可以和用户进行交互,同一时刻只有一个a ...

  8. android Activity生命周期(设备旋转、数据恢复等)与启动模式

    1.Activity生命周期     接下来将介绍 Android Activity(四大组件之一) 的生命周期, 包含运行.暂停和停止三种状态,onCreate.onStart.onResume.o ...

  9. Android Activity生命周期以及Fragment生命周期的区别与分析

    Android Fragment生命周期图: Activity生命周期图: 对照图: Fragment生命周期分析: 1. 当一个fragment被创建的时候,它会经历以下状态. onAttach() ...

随机推荐

  1. Web API应用架构设计分析(2)

    在上篇随笔<Web API应用架构设计分析(1)>,我对Web API的各种应用架构进行了概括性的分析和设计,Web API 是一种应用接口框架,它能够构建HTTP服务以支撑更广泛的客户端 ...

  2. 基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据

    最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重 ...

  3. Wojilu学习笔记 (02)

    使用RequireJS (1)整个页面,应该只有一个 <script src="" > 标签,并且放在页面底部,用来引入 RequireJS 和 main.js 文件 ...

  4. PHP表单数据写入MySQL代码

    <h1>插入操作</h1> <?php if(!isset($_POST['submit'])){ //如果没有表单提交,显示一个表单 ?> <form ac ...

  5. cefglue埋坑记录

    很少写博客,写的不好,请多多包含,主要是记录工作中的一些问题,和园子里朋友一起讨论学习. 写埋坑记录之前,我先介绍下为什么会使用这个webkit内核的浏览器组件,我是wpf项目使用富文本编辑器,话说w ...

  6. 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板

    [源码下载] 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板 作者:webabcd 介绍不可或缺 Windows Native 之 C++ ...

  7. Spring常用注解汇总

    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下: 使用注解之前要开启自动扫描功能 其中base-package为需要扫描的包(含子包). <context:component- ...

  8. 标签栏使用Demo二

    // //  PHTagViewFrame.m //  标签的使用二 // //  Created by 123 on 16/9/6. //  Copyright © 2016年 彭洪. All ri ...

  9. ThinkCMF-上传多个图片源码解读

    关键函数: /** * 多图上传 * @param dialog_title 上传对话框标题 * @param container_selector 图片容器 * @param item_tpl_wr ...

  10. InfluxDB学习系列教程,InfluxDB入门必备教程

    nfluxDB是一个当下比较流行的时序数据库,InfluxDB使用 Go 语言编写,无需外部依赖,安装配置非常方便,适合构建大型分布式系统的监控系统. 本文是一系列InfluxDB学习教程的目录,现主 ...