Android的开发中我们大部分都是和Activity打交道,而想很好的运用Activity首先必须要清楚Activity的生命周期。接下来我们就聊聊Activity的生命周期。
一、认识Activity
Activity的中文意思就是活动,代表手机屏幕的一屏,或是平板中的一个窗口,提供了和用户交互的可视化界面。Activity是用于处理UI相关业务的,比如加载界面、监听用户操作等事件。
二、Activity的状态
(一)、Running状态: 一个新的Activity启动入栈后,它在屏幕的最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态,Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可使用。当另外一个Activity被激活,这个将会被暂停。
(二)、Paused状态:当Activity处于此状态时,此时它依然与窗口管理器保持连接,系统继续维护其内部状态,它仍然可见,但它已经失去了焦点,故不可与用户交互。
(三)、Stopped状态: 当Activity 不可见时,Activity处于Stopped状态。当Activity处于此状态时,一定要保存当前数据和当前的UI状态,否则一旦Activity退出或关闭时,当前的数据和UI状态就丢失了
(四)、Killed状态:Activity被杀掉以后或者被启动以前,处于Killed状态。这是Activity已从Activity堆栈中移除,需要重新启动才可以显示和使用。
三、Activity的生命周期
(一)、先看下官方的基本生命周期图,可以从下图中了解Activity的大概生命周期:
(二)、生命周期的方法的介绍:
1.Activity正常的生命周期方法:
(1)onCreate方法:该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,我们在创建Activity时一般 都需要重写该方法,然后在该方法中做一些初始化的操作,如:创建view、绑定数据到view。
(2)onStart方法:start表示启动,这是Activity生命周期的第二个方法。此时Activity已经可见了,但是还没出现在前台,我们还看不到,无法与Activity交互。其实将Activity的初始化工作放在这也没有什么问题,放在onCreate中是由 于官方推荐的以及我们开发的习惯。
(3)onResume方法:当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态),onResume方法与onStart的相同点是两者都表示Activity可见,只不过onStart回调时Activity还 是后台无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图,我们也可以看出当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在 onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。
(4)onPause方法:当Activity要跳到另一个Activity或应用正常退出时都会执行这个方法。此时Activity显示在前台并可 见,我们可以进行一些轻量级的存储数据和初始化的工作,不能太耗时,因为在跳转Activity时只有当一个Activity执 行完 了onPause方法后另一个Activity才会启动,而且android中指定如果onPause在500ms即0.5秒内没有执行完毕的 话 就会强制关闭Activity。从生命周期图中发现可以在这快速重启,但这种情况其实很罕见,比如用户切到下一个Activity的途中按back键快速得切回来。
(6)onRestart方法:表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一 般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前 Activity页面时,onRestart方法就会被回调。 这里一般不做什么操作。
(7)onDestroy方法:该方法表示Activity生命周期中的最后一个方法,表示Activity方法将会被销毁,此时我们可以做 一些回收操作和最终的资源释放。这里需要提到的一点是,即使一个Activity被销毁后app内部的static变量是不会被销毁的,因为static变量是全局的,activity销毁但是该app的进程并没有被杀死。所以说这一点尤为需要注意我们的static变量的使用,否则稍有不慎再次启动该activity的时候该static变量就会是一个dirty data!
2、异常生命周期的两个方法:
(1)onSaveInstanceState方法:是用来保存UI状态的,在Activity杀死之前,你可以使用它保存你所想保存的东西,当 targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。
(2)onRestoreInstanceState方法:恢复界面的状态,是在onStart之后、onResume之前调用的。
(三)、了解了生命周期的方法,接下来我们来分析生命周期方法调用的顺序。
1.以下是验证方法调用顺序的实例代码:
public class MainActivity extends Activity {
public static final String TAG = "MainActivity"; Button bt; /** * Activity创建时被调用 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); Log.e(TAG, "onCreate is invoke!!!"); bt= (android.widget.Button) findViewById(R.id.bt); bt.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
android.content.Intent i = new android.content.Intent(MainActivity.this,SecondActivity.class); startActivity(i); }
}); }
/** * Activity从后台重新回到前台时被调用 */ @Override protected void onRestart() {
super.onRestart(); Log.e(TAG, "onRestart is invoke!!!"); }
/** *Activity创建或者从后台重新回到前台时被调用 */ @Override protected void onStart() {
super.onStart(); Log.e(TAG, "onStart is invoke!!!"); }
/** *Activity创建或者从被覆盖、后台重新回到前台时被调用 */ @Override protected void onResume() {
super.onResume(); Log.e(TAG, "onResume is invoke!!!"); }
/** * Activity被覆盖到下面或者锁屏时被调用 */ @Override protected void onPause() {
super.onPause(); Log.e(TAG, "onPause is invoke!!!"); }
/** *退出当前Activity或者跳转到新Activity时被调用 */ @Override protected void onStop() {
super.onStop(); Log.e(TAG, "onStop is invoke!!!"); }
/** *退出当前Activity时被调用,调用之后Activity就结束了 */ @Override protected void onDestroy() {
super.onDestroy(); Log.e(TAG, "onDestroy is invoke!!!"); }
}
2.下面我们分析各种情况下,生命周期方法执行顺序:
(1)我们先来分析Activity启动过程中所调用的生命周期方法,运行程序如下:
04-03 11:20:42.107 26915-26915/com.jiusi.equiview E/MainActivity: onCreate is invoke!!!
04-03 11:20:42.157 26915-26915/com.jiusi.equiview E/MainActivity: onStart is invoke!!!
onResume is invoke!!!
从Log中我们可以看出Activity启动后,先调用了onCreate方法,然后是onStart方法,最后是onResume方法,进入运行状 态,此时Activity已在前台显示。因此, Activity启动–>onCreate()–>onStart()–>onResume()依次被调用。
(2)当前Activity创建完成后,按Home键回到主屏。运行如下:
04-03 11:22:00.447 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:22:01.257 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
我们在Activity创建完成后,点击Home回调主界面时,可以发现此时onPause方法和onStop方法被执行,也就是点击Home键回到主界面(Activity不可见)–>onPause()–>onStop()依次被调用。
(3)当前Activity创建完成后,按Back键回到主屏。运行如下:
04-03 11:23:15.097 26915-26915/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:23:15.707 26915-26915/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
04-03 11:23:15.717 26915-26915/com.jiusi.equiview E/MainActivity: onDestroy is invoke!!!
我们在Activity创建完成后,点击back键返回时,相当于退出了当前Activity,Activity将被销毁,可以发现此时onPause方法、onStop方法、onDestroy方法被执行,也就是点击Back键返回时(Activity不可见)–>onPause()–>onStop()–>onDestroy()依次被调用。
(4)当我们在原有的Activity的基础上打开新的Activity时。运行如下:
04-03 11:26:00.767 29335-29335/com.jiusi.equiview E/MainActivity: onPause is invoke!!!
04-03 11:26:00.817 29335-29335/com.jiusi.equiview E/SecondActivity: onCreate is invoke!!!
04-03 11:26:00.827 29335-29335/com.jiusi.equiview E/SecondActivity: onStart is invoke!!!
onResume is invoke!!!
04-03 11:26:01.087 29335-29335/com.jiusi.equiview E/MainActivity: onStop is invoke!!!
我们可看到首先调用了原来的Activity的onPause方法,接着调用新的Activity的onCreate(),onStart(),onResume()方法,然后再调用原来Activity的onStop方法。也就是说 在原Activity的基础上开启新的Activity,原Activity生命周期执行方法顺序为–>onPause()–>onStop(),事实上跟点击home键是一样的。但是这里有点要注意的是如果新的Activity使用了透明主题,那么当前Activity不会回调onStop方法。同时我们发现新Activity(SecondActivity)生命周期方法是在原Activity的onPause方法执行完成后才可以被回调,这也就是前面我们为什么说在onPause方法不能操作耗时任务的原因了。
(5)当我们在新的Activity的基础上返回时。运行如下:
04-03 11:29:47.227 29335-29335/com.jiusi.equiview E/SecondActivity: onPause is invoke!!!
04-03 11:29:47.257 29335-29335/com.jiusi.equiview E/MainActivity: onRestart is invoke!!!
onStart is invoke!!!
onResume is invoke!!!
04-03 11:29:47.517 29335-29335/com.jiusi.equiview E/SecondActivity: onStop is invoke!!!
04-03 11:29:47.527 29335-29335/com.jiusi.equiview E/SecondActivity: onDestroy is invoke!!!
我们可以看到执行完当前Activity的onPause方法后,接着就依次执行前一个Activity的onRestart、onStart、onResume,此时前一个Activity已经显示在前台了,接着就调用了当前Activity的onStop、onDestroy方法,当前Activity就销毁了。
我们总结下方法的调用顺序,当Activity启动时,依次会调用onCreate,onStart,onResume,而当Activity退居后台时(不可见,点击Home或者被新的Activity完全覆盖),onPause和onStop会依次被调用。当Activity重新回到前台(从桌面回到原Activity或者被覆盖后又回到原Activity)时,onRestart,onStart,onResume会依次被调用。当Activity退出销毁时(点击back键),onPause,onStop,onDestroy会依次被调用,到此Activity的整个生命周期方法回调完成。
现在我们再回头看看之前的流程图,应该是相当清晰明了了吧。这就是Activity整个典型的生命周期过程。
3.生命周期异常方法:
Activity的 onSaveInstanceState 和 onRestoreInstanceState并不是生命周期方法,它们不同于 onCreate、onDestroy等生命周期方法,它们并不一定会被触发。当应用遇到意外情况(如:内存不足、用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState会被调用。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause适合用于数据的持久化保存。
在Activity被杀掉之前调用保存每个实例的状态,以保证该状态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (传入的Bundle参数是由onSaveInstanceState封装好的)中恢复。这个方法在一个Activity被杀死前调用,当该Activity在将来某个时刻回来时可以恢复其先前状态。
例如,如果ActivityB启用后位于ActivityA的前端,在某个时刻ActivityA因为系统回收资源的问题要被杀掉,A通过onSaveInstanceState将有机会保存其用户界面状态,使得将来用户返回到ActivityA时能通过onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢复界面的状态。
以上就是Activity生命周期的相关方法的一些介绍,有不合理之处请多指教!