在正常情况下,Activity会经历如下的生命周期。
(1) onCreate:表示Activity正在被创建,在这个方法中,可以做一些初始化的工作,比如调用setContentView去加载界面布局资源、初始化Activity所需的数据等。
(2)onStart:表示Activity正在被启动,这时Activity已经可见了,但是还没有出现在前台,还无法和用户交互。这个时候其实可以理解为Activity已经显示出来了,但是我们还看不到。也就是这个方法在Activity由不可见变成可见的时候调用。
(3)onResume:表示Activity已经可见了,并且出现在前台并开始活动,可以与用户进行交互了。要注意这个和onStart的对比,onStart和onResume都表示Activity已经可见,但是onStart的时候Activity还在后台,onResume的时候才显示到前台。
(4)onPause:表示Activity正在停止,正常情况下,紧接着onStop就会被调用。在这个时候Activity还是可见的,如果再回到当前的Activity,那么onResume会被调用。如,用户启动一个Dialog Activity,没有把原来的Activity完全盖住,那么原来的Activity就会进入onPause状态,此时返回原来的Activity就会调用onResume。我们通常会在这个方法释放掉一些CPU资源,以及保存一些关键数据,但这个方法一定要快,不然会影响新的Activity的显示,onPause必须先执行完,新的Activity的onResume才会执行。
(5)onStop:表示Activity即将停止,执行完这个方法后Activity就进入完全不可见状态,可以做一些稍微重量级的回收工作,同样不能太耗时。
(6)onDestroy:表示活动即将被销毁,这是Activity生命周期中的最后一个回调,在这里,我们可以做一些回收工作和最终资源的释放。
(7)onRestart:表示Activity正在重新启动。一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart就会被调用。这种情形一般是用户行为所导致的,比如用户按Home键切换到桌面或者用户打开了一个新的Activity,这时当前的Activity就会暂停,也就是onPause和onStop被执行了,接着用户又回到了这个Activity,就会出现这种情况。
正常情况下,Activity的常用生命周期就只有上面7个,这7个方法除了onRestart方法,其他都是两两相对的,从而又可以将活动分为3种生存期。
完整生存期。Activity在onCreate方法和onDestroy方法之间所经历的,就是完整生存期。一般情况下,一个Activity会在onCreate方法中完成各种初始化操作,而在onDestroy方法中完成释放内存的操作。
可见生存期。Activity在onStart方法和onStop方法之间所经历的,就是可见生存期。在可见生存期内,Activity对于用户总是可见的,即便有可能无法和用户进行交互。我们可以通过这两个方法,合理地管理那些对用户可见的资源。比如在onStart方法中对资源进行加载,而在onStop方法中对资源进行释放,从而保证处于停止状态的Activity不会占用过多内存。
前台生存期。Activity在onResume方法和onPause方法之间所经历的就是前台生存期。在前台生存期内,活动总是处于运行状态的,此时的活动是可以和用户进行交互的,我们平时看到和接触最多的也就是这个状态下的Activity。
为了能更好理解Activity各种生命周期的切换过程,Android官方提供了一张活动周期的示意图,如图所示:
针对上图,这里再附加一些说明,分如下几种情况。
(1)针对一个特定的Activity,第一次启动,回调如下:onCreate -> onStart -> onResume。
(2)当用户打开新的Activity或者切换到桌面的时候,回调如下:onPause -> onStop。这里有一种特殊情况,如果新Activity采用了透明主题,那么当前的Activity不会回调onStop。
(3)当用户再次回到原Activity时,回调如下:onRestart -> onStart -> onResume。
(4)当用户按Back键回退时,回调如下:onPause -> onStop -> onDestroy。
(5)当Activity被系统回收后再次打开,生命周期方法回调过程和(1)一样,注意生命周期方法是一样的,不代表所有过程一样。
异常情况下的生命周期分析
1. 资源相关的系统配置发生改变导致Activity被杀死并重新创建
当系统配置发生改变后,Activity会被销毁,其onPause、onStop、onDestroy均会被调用,同事由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。需要强调一点的是,这个方法只会出现在Activity被异常终止的情况下,正常情况下系统不会回调这个方法。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。onRestoreInstanceState和onCreate方法,两者的区别是:onRestoreInstanceState一旦被调用,其参数Bundle savedInstanceState一定是有值的,不用额外地判断是否为空;但是onCreate不行,onCreate如果正常启动的话,其参数Bundle savedInstanceState为null,所以必须要额外判断。
2. 资源内存不足导致低优先级的Activity被杀死
Activity按照优先级从高到低,可以分为如下三种:
(1)前台Activity——正在和用户交互的Activity,优先级最高。
(2)可见但非前台的Activity——比如Activity中弹出了一个对话框,导致Activity可见但是位于后台无法和用户直接交互。
(3)后台Activity——已经被暂停的Activity,比如执行了onStop,优先级最低
当系统内存不足时,系统就会按照上述优先级去杀死目标Activity所在的进程,并在后续通过onSaveInstanceState和onRestoreInstanceState来存储和恢复数据。如果一个进程中没有四大组件在执行,那么这个进程将很快被系统杀死,因此,一些后台工作不适合脱离四大组件而独立运行在后台中,这样进程很容易被杀死。比较好的方法是将后台工作放入Service中从而保证进程有一定的优先级,这样就不会轻易地被系统杀死。