Activity是Android四大组件之首,其重要性不言而喻,Activity的生命周期更是我们了解Android工作机制的重中之重。我们一般将Activty的生命周期做两种情况下的理解,即正常情况和异常情况。

  所谓正常情况下的生命周期,指的是在有用户参与的情况下,Activity所经过的生命周期的改变;

  所谓异常情况下的生命周期,指的是Activity被系统回收或者由于设备的Configuration发生改变从而导致Activity被销毁重建。

  接下来我们来依次深入了解一下这两种情况下Activity的生命周期。

正常情况下的生命周期分析

  正常情况下Activity的生命周期如下图所示:

  (1) onCreate() :Activity正在被创建时调用的生命周期函数;

  (2) onStart() :Activity能被用户看到时候调用的生命周期函数;

  (3) onResume() :Activity获取用户焦点的时候调用的生命周期函数;

  (4) onPause() :Activity失去用户焦点的时候调用的生命周期函数;

  (5) onStop() :Activity不能被用户看到的时候调用的生命周期函数;

  (6) onDestroy() :Activity即将被销毁的时候调用的生命周期函数;

  (7) onRestart() :Activity不可见而没有被销毁的情况下重新可见时调用的生命周期函数。

【注意】:

  (1)生命周期函数基本上是配对的,如 onCreate() 方法和 onDestroy() 方法、onStart() 方法和 onStop() 方法、onResume() 方法和 onPause() 方法等;

  (2)当打开一个新的 Activity 时,旧 Activity 的 onPause() 方法会先于新 Activity 的 onResume() 方法执行;

  (3)由于上一条,因此不能在 onPause() 方法中做太过好事的操作,较为耗时的操作应该尽量放在 onStop() 方法中执行,从而使新 Activity 尽快显示出来。

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

  开头说过,导致Activity生命周期异常的情况有两种:Activity的配置发生改变,以及Activity被系统回收。

情况1:资源相关的系统配置改变导致Activity被杀死并重建

  Activity中有很多配置信息,如果这些信息发生改变,那么Activty就可能会被杀死并重建。但是,我们可以通过代码来干预这些配置,设置某些配置即使发生改变,Activity也不会被杀死。系统配置中有很多内容,如果当某项内容发生改变后,我们不想系统重新创建Activity,则可以在Manifest文件中给这个Activity指定configChanges属性,示例代码如下:

<activity
android:name=".ui.activity.LoginActivity"
android:configChanges="orientation|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize|stateVisible">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

  例如,我们可以通过设置 android:configChanges 属性来禁止设置在横竖屏切换后被杀死并重建,只需要在Manifest文件的 <activity> 标签中添加 android:configChanges="orientation|keyboardHidden|screenSize" 即可。

  更多的配置选项请参考下表:

  【注意】:不同的配置选项之间可以通过“ | ”符号分隔。

  如果我们不为Activity设置configChanges属性,那么当Activity被杀死重建之后,我们还能不能获取到之前的数据了呢?答案是可以的,我们可以通过Android系统为我们提供的两个方法 onSaveInstanceState() 和 onRestoreInstanceState() 来存储和取出数据。当Activity在异常情况下需要重新创建时,系统会默认为我们保存一些数据,如当前Activity的视图结构、文本框中用户输入的数据、ListView滚动的位置等。  

  如果我们需要将自定义的数据保存下来,可以重写 onSaveInstanceState() 和 onRestoreInstanceState() 这两个方法,使用Bundle对象存储自定义的数据,进行数据传递。

  【注意】:

  (1) onSaveInstanceState() 在onStop()方法之前执行, onRestoreInstanceState() 在onStart()方法之后执行;

  (2) onSaveInstanceState() 和 onRestoreInstanceState() 在正常情况的生命周期中不会被调用,只有当生命周期发生异常时才会被调用;

  (3) onCreate() 方法中有一个Bundle类型的参数,这个参数也是用于接收异常情况下传递的保存数据的,但是不建议在onCreate()方法中处理保存的数据,原因有二:第一,onCreate()方法中处理的事情已经够多了,我们应该将恢复数据的操作提到其他生命周期函数中;第二,每次开启Activity都会调用onCreate()方法,如果在onCreate()方法中恢复数据,那么每次都需要判断该Activity是否被重启了,即Bundle对象是否为空,这样很繁琐;

  (4)和Activity相同,View中也有 onSaveInstanceState() 和 onRestoreInstanceState() 两个方法。Android系统保存和回复View层次结构中的数据的方法使用了委托思想,其流程是这样的:首先Activity被异常终止时,Activity会调用 onSaveInstanceState() 方法去保存数据,然后Activity委托Window去保存数据,接着Window再委托它上面的顶层容器去保存数据,最后顶层容器再去一一通知它的子元素来保存数据。数据恢复过程也是类似的,这样就保证了View层级树中的所有View中的数据都被保存并恢复了。

情况2:资源内存不足导致低优先级的Activity被杀死

  这里我们需要先了解一下Andorid系统中Activity的优先级分类,从高到低可以分为以下三类:

  (1)前台Activity——正在和用户交互的(获取用户焦点的)Activity,优先级最高;

  (2)可见但非前台Activity——用户可见但没有获取用户焦点的Activity;

  (3)后台Activity——用户不可见、已经被暂停了的的Activity,优先级最低。

  当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并在后续通过 onSaveInstanceState() 和 onRestoreInstanceState() 来存储和恢复数据。

  【注意】:如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,因此,一些后台工作不适合脱离四大组件而独立的运行在后台中,这样进程将很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。

【Android - 组件】之Activity生命周期的全面分析的更多相关文章

  1. Android 组件系列-----Activity生命周期

    本篇随笔将会深入学习Activity,包括如何定义多个Activity,并设置为默认的Activity.如何从一个Activity跳转到另一个Activity,还有就是详细分析Activity的生命周 ...

  2. Android-管理Activity生命周期 -停止和重启Activity

    停止和重启activity在activity的生命周期中很重要,它能让用户感觉你的app总是激活的而且不会丢失他们的进度.activity在下面的这些情况会停止和重启: 用户打开常用app窗口然后从你 ...

  3. Android-管理Activity生命周期 -暂停和恢复一个Activity

    在正常的使用app时,前台的activity有时候会被可见的组件阻塞导致activity暂停.比如,当打开一个半透明的activity(就像打开了一个对话框),之前的activity就会暂停.只要ac ...

  4. Android-管理Activity生命周期 -重新创建Activity

    按照正常的app行为,很少情况下activity会销毁,只有当用户点击了返回按钮或者activity通过调用finish()发出销毁信号.系统也有可能销毁activity如果它是停止状态并且很久没有使 ...

  5. Android-管理Activity生命周期 -开始一个Activity

    很多程序都是从main()方法开始启动的,和其他程序不同,android是在activity生命周期的特定状态的特定回调方法中初始化代码的.activity启动和销毁的时候都用很多回调方法. 这里将要 ...

  6. 【Android实验】第一个Android程序与Activity生命周期

    目录 第一个Android程序和Activity生命周期 实验目的 实验要求 实验过程 1. 程序正常启动与关闭 2. 外来电话接入的情况 3. 外来短信接入的情况 4. 程序运行中切换到其他程序(比 ...

  7. Android 四大组件之Activity生命周期

    写这篇博文之前,已经对android有一定的了解和认识.这篇博文主要讲述android的Activity的生命周期,这是android开发者必须掌握的知识.android的Activity组件拥有7个 ...

  8. 深入剖析Android四大组件(一)——Activity生命周期具体解释

    1.管理Activity的生命周期 不管是正在执行的Activity还是没有执行的Activity,它们都接受Android的框架管理,这使得Activity处于不同的生命周期. ①Activity的 ...

  9. Android体系结构及activity生命周期

    Android的系统架构采用了分层架构的思想,如图1所示.从上层到底层共包括四层,分别是应用程序程序层.应用框架层.系统库和Android运行时和Linux内核 Android的系统架构图    每层 ...

随机推荐

  1. 【Linux系列】Linux基础知识整理

    Linux操作系统在服务器领域广泛的使用到,作为一个后台开发工程师很有必要了解Linux相关的知识. 本篇日志是我学习Linux过程中的简单记录和总结.本着"理论够用,实践为主"的 ...

  2. Linux性能分析

    生产环境服务器变慢,诊断思路和性能评估 整机:top 代码 public class JavaDemo2 { public static void main(String[] args) { whil ...

  3. window10系统下,彻底删除卸载mysql

    本文介绍,在Windows10系统下,如何彻底删除卸载MySQL...1>停止MySQL服务开始->所有应用->Windows管理工具->服务,将MySQL服务停止.2> ...

  4. 学习笔记66_DBSCAN聚类算法

  5. 介绍几个常用的makefile函数

    addprefix. $(addprefix <prefix>, <name1 name2 ...>) 功能:把<prefix>加到name序列中的每一个元素前面. ...

  6. [考试反思]0926csp-s模拟测试52:审判

    也好. 该来的迟早会来. 反思再说吧. 向下跳过直到另一条分界线 %%%cbx也拿到了他的第一个AK了呢. 我的还是遥不可及. 我恨你,DeepinC. 我恨透你了.你亲手埋葬所有希望,令我无比气愤. ...

  7. NOIP模拟测试33

    这次考试很失败. T1sb题,40分钟切了,当我打完对拍全过去上厕所的时候,碰到了yxm. yxm:我又自闭了,没有一点进展. 我:…… yxm:你会做几个? 我(思考再三):T1只会暴力. (我这么 ...

  8. 爬虫学习--Day4(小猿圈爬虫开发_2)

    requests模块 - urllib模块 - requests模块 requests模块:python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高.作用:模拟浏览器发送请求. 如 ...

  9. 苹果审核ipv6海外解决思路-About APP Store

    原始简书文章地址(也是我自己的) 首先声明,一我不负责涉及你们内部服务器. 二是好好读文章,别人能过,你们也能过 苹果6月1日出的IPV6协议阻碍了国内大多数积极开发者,我司也不外乎,经过三次被拒后, ...

  10. PTA刷题记录(1)

    团队天梯赛-------(2)分值:20 题目要求:你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** ***   *  *** ***** 所谓“沙漏形状” ...