通过《Activity初步介绍》课程我们知道Activity就是一个和用户交互的一个界面,既然是一个界面,它肯定有很多状态,比如正处于交互状态,后台状态,销毁状态。而Activity的每次状态改变都会被系统回调自己的方法,我们称之这些方法为Activity的生命周期方法。
一个Activity本质上有四种状态:
下面这张图是一张经典的Activity的生命周期图,一个矩形代表一个生命周期方法,带颜色的椭圆代表了Activity的主要状态:
从图中可以看到,Activity的全部生命周期方法是从onCreate 到onDestroy, 一个Activity会在onCreate 中初始化Activity的全局资源,在onDestroy 释放Activity所占用的资源,例如,我们在onCreate创建一个线程来运行,在onDestroy中停止这个线程。
从调用onStart的时候Activity开始可见,调用onResume 后Activity处于可交互状态,调用onPause后Activity失去焦点,调用onStop后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观察Log信息。
上面我们已经说明Activity有四种状态,第四种状态是被销毁的状态,所有当Activity从创建后到销毁前实际上只有三种状态:Resumed、Paused和Stopped。
当Activity处于paused和stopped状态的时候随时有可能因为内存不够而被系统回收,系统可以调用Activity的finish()方法或者直接杀掉Activity所在的进程来回收Activity所占用的资源,如果这个Activity再被打开的时候(已经被杀死)就会重新创建一个新的Activity,那么原来Activity所持有的数据就会丢失,这是很差的用户体验,为了能够恢复原来的数据,Activity还有一个回调方法onSaveInstanceState():
onSaveInstanceState有一个Bundle类型的参数, Bundle在android数据传递起到了很大的作用,它实际上类似java的Map,是用来存数据的一个集合类,我们再看一下onSaveInstanceState的调用场景:
在另外一个Activity成为一个前台Activity的时候,会调用onSaveInstanceState,可以重写此方法为Bundle 填装要保存的数据,如果Activity被销毁了,就会重新调用onCreate,请注意观察onCreate方法是有一个参数Bundle的(默认是null),这时候我们就可以从Bundle中获得丢失的数据。要注意的是Activity在销毁前会不会调用onSaveInstanceState是没有保证的,比如直接按返回键Activity是被销毁了,但是onSaveInstanceState是不会调用的,因为用户已经确认要关闭当前的Activity,如果系统调用onSaveInstanceState,它一般在onStop之前,也有可能在onPause之前。
然而,如果我们不实现onSaveInstanceState,onSaveInstanceState默认是会调用当前Activity中所有的view的onSaveInstanceState的实现,view会自动的保存自己的信息(例如输入框的内容)并在Activity重新创建的时候自动恢复,当然,前提是view必须有一个唯一的ID。尽管onSaveInstanceState默认实现可以恢复Activity中view自己的状态,但是你可能还需要一些附加信息,例如一些成员变量,所以重新onSaveInstanceState也是很有必要的。
因为onSaveInstanceState方法有可能不会在Activity销毁之前被调用,所以onSaveInstanceState一般用来保存临时数据,比如view的状态之类,如果你想持久化的存储数据,我们可以在onPause方法把这些数据存入数据库,在onResume方法取出这些数据,一个比较方便测试保存数据的方法就是旋转你的设备,横竖屏切换Activity默认是会被销毁掉然后创建一个新的Activity,如果Activity的信息没有丢失,说明Activity在销毁之前已经保存了数据。
总结:
Activity销毁前保存数据可以在onSaveInstanceState和onPause中做,onSaveInstanceState保存临时数据,onPause保存持久数据。
熟悉Activity的生命周期在具体工作的时候有很大的用处,你会明白你的代码应该写在哪个生命周期方法里面,例如要给Activity一个布局,我们应该在onCreate方法中调用setContentView方法,因为onCreate就是初始化Activity的全局资源的时候调用的,只要是初始化,一般都只会执行一次,Activity也是一样,我们在初始化的时候给Activity指定布局。如果你要用某个类的方法,也应该在onCreate中创建该类的对象,还有,如果你要开发一个视频播放器的项目,我们是不是应该在Activity处于前台的时候才能播放,失去焦点的时候就要停止播放,这时候我们就可以在onPause中调用视频暂停的方法,在onResume中调用视频播放的方法。