Android Activity 生命周期详解

1. 什么是Activity?

  1. Activity作为Android四大组件之一,它有着举足轻重的地位,每一个Activity都会获得一个用于绘制其用户界面的窗口,Activity是一个view对象的容器,通过Window类的setContentView()方法添加到Activity上,最终提供与用户交互的界面;
  1. Activity是上下文对象 Context的子类, 并且实现了Window.callback,KeyEvent.callback 这两个接口,因此 Activity 可以响应和处理用户与窗口的交互事件,以及键盘相关的输入事件;
  2. 一个Android应用通常由一个或者多个Activity 组成;如果是多个Activity,一般会指定应用中的某个 Activity 为“主” Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个Activity 通过使用Intent(意图)均可启动另一个Activity,这里使用的是IPC机制。 每次启动一个新的Activity 启动时,前一 Activity 便会停止,但系统会在回退桟中保留该 Activity,而新启动的Activity可以放如该栈顶也可以设置其启动方式放入新的回退桟,这就和Activity四种启动方式有关了。

附上一张图,对Activity有一个更直观和全面的认识:
这里写图片描述

对Activity有了一个比较直观的认识后,我们自然想到的是怎么使用它,其实对于Activity google对其封装的还是挺厉害,开发者使用时主要就是继承Activity,通过setContentView()方法设置布局界面,然后重写它的几个生命周期函数;而跳转新的Acitivty更简单,通过一个Intent然后调用startActivity方法即可;

2. Activity生命周期

其实对于Activity最重要的就是搞清楚它的各个生命周期函数,只有这样我们才能知道Activity在各个生命周期阶段需要做什么事,那些事不适合做,这对于编写高质量的App是至关重要的;

Activity是通过回退桟来管理的,此时Activity可呈现出四种状态:
(1) 当Activity位于回退栈桟顶时,此时将显示在屏幕上,用户可与之交互,此时Activity处于运行状态
(2) 当Activity失去了焦点但依然可见(如栈顶Activity尺寸小没有完全覆盖屏幕,或者栈顶Activity是透明的),此时Activity处于暂停状态
(3) 当Activity被新的Activity或者应用完全遮住(新Activity不透明),因此Activity已经对用户不可见,此时Activity处于停止状态
(4) 当Activity被完全退出或者App进程完全退出时,Activity将会回调onDestory方法,之后Activity将被销毁,Activity将处于销毁状态

下面我们主要阐述Activity的生命周期:
同样我们先附上图(来自Android官方文档):
这里写图片描述

1. 首先对Activity主要生命周期函数做介绍:

(1) onCreate

Activity生命周期的第一个方法,表示Activity正在被创建,在该方法中通过setContentView 方法加载xml编写的布局文件,然后通过findByViewId方法获取控件;
onCreate()方法在Activity整个生命周期中只会调用一次,所以该方法中就可以做一些大致只需要做一次的工作,如:一些变量的初始化,资源的加载,初始化控件以及事件的绑定等;
由于此时view还没有加载出来,因此该方法中不能开启动画的;

注:onCreate()的官方文档注释,建议 setContentView()、findViewById() 在 onCreate() 中调用,但在onStart()中调用 setContentView()、findViewById() 功能也是正常的,只是不建议,并且很少会这样做;

(2) onStart

Activity正在启动,此时Activity已经看见,但是没有展现在前台,没有获取到焦点,当然也就不能与用户交互;
因为该方法是Activity重新回到前台时第一个回调的方法,因此在该方法里我们可以去检查某些必须的系统特性是否可用,比如网络是否在连接, GPS是否打开等类似的功能;
该方法中我们通常初始化一些变量,当然这些变量必须是在Activity处于前台的时候才能够被响应;

(3) onResume

Activity可见可交互;
如果Activity是重新打开,此时就需要在该方法中重新实例化在onPause()中释放的资源;
初始化在前台显示时需要的资源,如:动画、播放视频,此外建议在onResume()中打开独占设备,比如相机,之所以在该方法中打开是因为当打开新的Activity时,首先会onPause掉旧Activity,然后在onCreate, onStart, onResume新Activity,如果之前旧Activity已经打开了独占设备(相机), 那此时onPause旧Activity时就可以释放掉独占设备(相机),那么打开的新Activity就能够使用独占设备(相机)了;

(4) onPause

Activity已经暂停,可见但不在前台,因此也不可交互;
该方法中需要持久化用户数据、停止动画,暂停正在播放的视频等不太耗时的操作;
释放部分占用的系统资源(尤其是独占设备),如:相机, GPS等,设置有时会让该Activity断开网络连接,因为这些工作会大幅度占用系统资源,增加电耗或者流量消耗;
因为打开新的Activity前回去回调旧Activity的onPause方法,因此onPause方法中不能做太耗时的操作(如,数据库读写,IO操作),否则调新的 Activity 在切换时可能会出现卡顿现象,这是用户不想看到的;
耗时的清理工作应该放在onStop方法中;

(5) onStop

Activity即将停止,此时当然不可见;
耗时的清理工作应该放在onStop方法中;
Activity 在此状态时仍然存在于内存中,如果在系统内存不够时,系统接下来很快会销毁掉该Activity,在极端情况下,直接 kill Activity 且不执行onDestroy()函数。所以务必在onStop()函数中就清理掉可能引起内存泄露的资源,当然更极端的时系统内存已严重不足,导致系统无法保留该进程的情况下,onStop() 可能都不会被执行;

(6) onDestory

Activity即将被销毁,
很多情况下 Activity 是不需要定义这个函数,因为在onPause()和onStop()中,大多数的清理工作都已经完成了。但是,如果在onCreate()中定义了后台线程,或者可能引起内存泄露的代码,那就需要在onDestroy()中清理,如,静态对象持有其他Activity的引用,广播注销等操作;

(7) onRestart

Activity正在被重新启动
在原Activity没有销毁时重新要回到该Activity时会回调该方法,紧接着会回调onStart方法,一般在该方法中恢复用户数据;

其实Activity生命周期函数可以看成是成对的,onCreate和onDestory成对,onStart和onStop成对,onResume和onPause成对,这在上述每个回调函数的介绍中也可以看出来
这里写图片描述

2. 下面阐述几种比较常见的情况:

(1) 单个A Activity启动回调流程

 onCreate
 onStart
 onResume

(2) 当用户按下home键时

 onPause
 onStop

(3) 当用户再次回到原Activity时

 onRestart
 onStart
 onResume

(4) 在A Activity的基础上,打开新的B Activity,此时需要注意的问题是B Activity的大小和透明度

 a. B Activity完全覆盖A Activity,并且B Activity是不透明的:
  A Activity: onPause
  B Activity: onCreate --> on Start --> onResume
  A Activity : onStop

 b. B Activity因为尺寸小没有完全覆盖A Activity,或者B Activity是透明的, 此时A Activity的onStop方法是不会被执行的
  A Activity: onPause
  B Activity: onCreate --> on Start --> onResume

(5) 当用户按back键时

 onPause
 onStop
 onDestory

 
 
笔者水平有限,如有错误,欢迎指正,谢谢!

posted @ 2016-07-29 09:30  絮雨斜阳  阅读(2362)  评论(0编辑  收藏  举报