android 基础02 - Activity 的生命周期及状态

时间:2023-03-09 04:28:52
android 基础02 - Activity 的生命周期及状态

返回栈

  Android 中的 Activity 是可以层叠的,当我们启动一个新的 Activity 时,就会覆盖在原有的 Activity 之上,

点击 Back 会销毁当前 Activity,下面的(上一个 Activity)就会显示出来。

  Android 中使用任务(Task) 来管理 ACtivity,一个任务就是放在放在栈(Stack)中的一系列 Activity 的集合。这个栈就被称作 返回栈(Back Stack),栈是一种后进先出(Last In First Out)的数据结构,当我们启动一个新的 Activity 时,它会被推入栈,并且处于栈顶的位置,当我们点击 Back 或者调用 finish() 时,Activity会被销毁,此时Activity 就会被从返回栈中弹出,上一个入栈的 Activity 就会显示出来,系统总是显示返回栈顶的 Activity 给用户。

Activity 的状态说明

  Activity 是 Android 四大组件中最基本的,Activity 存在多种状态,当 Activity 的状态发生改变时,对应的生命周期的事件方法便会被调用,通知 Activity 执行某些代码去适应改变。

  Activity 的状态大致可以分为 如下几种:

  • Active/Running

      

     当一个 Activity 处于 Activity 栈的顶端时,Activity 处于 Active/Running 状态,此时 Activity 被认为具有最高的优先级,只有在一些特殊的情况下才会被 Android 系统杀死,例如 Acitivity 尝试使用的内存空间大于系统分配的最大内存空间时,此时会导致该 Acitivity 无法响应用户的操作,此时 该 Activity 便可能会被 Android 系统杀死。

  • Paused

  当设备休眠、一个新的 Activity 覆盖了当前的 Activity(前一个 Activity 部分可见) 时,则 前一个Activity被认为处于Paused 状态,,此时的 Activity 并没有被系统杀死,仍然被附加在 Window Manager 上,可以这么理解,处于此种状态的 Activity 具有仅次于 Active 状态的Activity 的优先级,只有当在杀死该状态的 Activity 可以满足 Active 状态的 Activity 的资源需求或维持 Active 状态的 Activity 的可响应状态稳定的情况下,系统才会杀死处于该状态下的 Activity。

  • Stopped/Background

  当 Activity A被另外一个 Activity B完全隐藏时,则 A 处于 Stopped/Background 的状态,此时 Android 系统会尽可能长的去维护 Activity 的状态或成员信息,此状态下的 Activity 优先级最低,当需要满足高优先级的 Activity的资源需求时,系统会第一时间杀死处于该状态下的 Activity.

  • Restroed

  当一个 Activity 以任何方式从 Paused 转变为 Stopped 时,都可能会被 Android 系统将其从内存中移除。当用通过导航 返回到一个 Activity 时,则这个 Activity 必须 Restored 来恢复之前的保存状态,然后才能展现给用户。

生命周期中的方法说明

android 基础02 - Activity 的生命周期及状态

方法名称 描述
onCreate 当 Activity 第一次创建时调用
onStart 当 Activity 每次出现时调用,既 Activity 由不可见变为可见时调用
onResume 当 Activity 准备好与用户进行交互时调用,此时的 Activity 一定处于返回栈的栈顶,且一定处于运行状态
onPause 当Activity 被Pause后,Activity不再接受用户的输入且不再执行任何代码,当一个Activity被醒(Resume)时,前一个Activity 便处于 Paused 状态,既 Activity 消失时调用
onStop 当 Activity 消失后调用
onDestory 当 Activity 被系统销毁前调用
onRestart 当 Activity被停止后重新唤醒时调用
  • OnCreate

  这个方法是创建 Activity 是调用的第一个方法,通常进行一些 Activity 的部署初始的工作,例如: 创建视图、变量初始化、静态数据绑定

	protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// do something else
}

  OnCreate 传递一个 Bundle 参数,这是一个字典类型,用于在 Activity 传递和存储 Activity 的一些状态信息和一些对象,如果 Bundle 不为 Null,则表示该 Activity 被重新唤醒,需要从之前的实例中回复之前的状态值。

  • OnStart

  OnStart 方法通常在 OnCreate 方法完成后被调用,当我们需要在 Activity 出现前立刻执行一些任务时,例如刷新该 Activity中的某些 View时,我们便可以对该方法进行重写,将这些任务放在该方法中去执行。

  • OnResume

  OnResume 方法通常在 OnStart 方法完成后被调用,此时系统已做好与用户进行交互的准备,在这个方法中适合进行如下的一些操作:

 	1. 启动动画
2. 监听 GPS 的数据更新
3. 展现一些 Dialog
4. 绑定一些事件的处理程序

注意: 在 Onpuse 方法中进行的操作,在 OnResume 中必须进行对应的逆向操作,这个方法的执行必须可以保证将 Activity 的状态恢复到调用 OnPuse 之前完全一致的状态。

  • OnPuse

  当 Activity 将要被系统放入后台或被部分隐藏时调用 *OnPuse,当 Activity 需要执行如下操作时,可以对该方法进行重写:

1. 将未保存的改变转换为持久的数据
2. 清除或销毁其它对象消耗的资源
3. 注销外部事件的或通知的处理程序,防止 Activiy 内存溢出
4. 如果 Activity 中有 Dialog 显示,则需要调用 Dialog 的 Dismiss 方法

  在 OnPause 之后,调用 OnResume 将使其恢复到前台,调用 OnStop 方法将 Activity 在后台挂起。

  • OnStop

    当 Activity 消失时调用,如下情况时该方法会被系统调用

    1. 一个新的 Activity 被启动并覆盖了当前的 Activity
    2. 一个后台的 Activity 被推到前台,则会调用前一个 Activity 的 OnStop 方法
    3. 一个 Activity 被销毁时

  OnStop 方法并不总是能在内存低的情况下调用,例如当 Android 系统迫切的需要资源并且不能将 Activity 转入后台时,这时候最好不要依赖当 Activity 将要被销毁时会调用其 OnStop 方法,如果 Activity 将要消失,则下一个将要被调用的生命周期方法将会是 OnDestory ,如果 Activity 通过用户交互返回屏幕时,将要被调用生命周期方法是 OnReStart.

  • OnDestory

  这个方法是 Activity 实例被销毁(从内存中移除)前调用的最后一个方法,在极端情况下,Android 系统会杀死维护某个 Activity 的进程,这将导致该 Activity 的 OnDestory 方法无法被调用,大多数的 Activity 都不会实现这个方法,因为大部分的清理和关闭工作在 OnStop 和 OnPause 中已经完成了,OnDestory 通常被重写用来清理一些长时间占用、可能发生内存泄漏的资源,例如一些在 OnCreate 创建的一些后台线程等。

  • OnRestart

  这个方法在 Activity 停止后再次被启动时调用,当用户处于应用的某个 Activity 页面时点击 Home 退回到首页,此时该 Activity 并不会被销毁,而是挂起到后台,之后用户通过任务管理器(Task Manager)或其它类似的应用再次回到之前的 Activity 时,系统便会调用该方法来还原到退出之前的状态。

  并没有一条具体的准则来规定哪些逻辑需要放在 OnRestart 方法中来实现,因为不论是 Activity 即将被创建或即将被重启时这个方法都会被调用,因此与 Activity 相关的资源的初始化要放在 OnCreate 中执行而不是 OnRestart 中。


注意: 在大多数的 Android 设备中都有两个虚拟按键,一个 Home 键,一个返回按键,当一个应用只有一个 Activity 的情况下,点击 Home 和 返回键看起来会有类似的效果,但两者之间还是有区别的,当点击 Home 时,Activity 会被挂起到后台,而点击返回按钮时,会直接杀死当前 Activity 。

Activity 状态管理

  当一个 Activity 被停止或者被销毁时,Android 系统提供了保存 Activity 状态的时机,以方便后续的使用,在 Activity 的生命周期中,系统提供了两种方式去保存 Activity 的状态

  • 在 Bundle(字典类型的数据结构实例)中存储一些简单的类型,如字符串、数字等
  • 自定义类型去维护一些复杂的类型,如 BitMap 等,Android会使用该类型去保存状态
Bundle

  保存 Activity 最基本的方式是使用 称作 Bundle 的存储键值对的字典集合。当使用 OnCreate 创建 Activity 时,会传递一个 Bundle 类型的参数,这个 Bundle 便可以用来存储一些 Activity 实例的状态信息,通常 Bundle 只适合存储一些简单的数据类型,因为复杂的类型不能被快速高效的序列化为 键值对(key/value

  Activity 提供了一些方法去帮助通过 Bundle 来检索和保存 实例状态:

  • OnSaveInstanceState

  在 Activity 被销毁时,Android 系统会调用此方法,可以重写此方法去 持久化(persist)一些键值对类型的状态信息

  • OnRestoreInstanceState

  该方法在 OnCreate 完成后调用,用以在 Activity 初始化完成后恢复状态

android 基础02 - Activity 的生命周期及状态

  

使用Bundle保存状态的局限性

  尽管使用 OnSaveInstanceState 方法可以方便的保存一些相对 Activity 透明的数据,但其也具有一些局限性

  • 在某些特殊情况下该方法不能保证该方法总是被调用,在 点击 Home 按键或返回按键退出当前 Activity 时,该方法不会被调用
  • 能够保存的类型仅限于简单类型(例如字符串、数值类型等)
  • 保存在 Bundle 中的数据会经过序列化处理,在加载时会导致延迟
保存复杂的数据类型

  

  为了保存复杂类型对象的数据,我们可以重写 Activity 的 OnRetainNonConfigurationInstance 方法,该方法返回一个 Java.Lang.Object 类型的实例,其中包含有需要持久化的数据。

	public overide Java.Lang.Object OnRetainNonConfigurationInstance(){
MyDataObj do = new MyDataObj();
return do;
}

  在 OnCreate 中使用

	MyDataObj do = (MyDataObj)LastNonConfigurationInstance;

  当我们从网络上获取到的某些资源可以使用这种方式保存,那么当 Activity 恢复时无须重复获取,以便达到资源的重复使用