Android - Acitivty生命周期 理解

1、Activity的四种状态

理解Activity的生命周期之前,先理解对android的生命周期的特点进行整理,从而归纳出的Activity的四种活动状态。

那么,通常来说,一个Activity的整个生命周期内,会经历如下的几种状态:


  • 运行状态:

         * 当一个Activity位于返回栈栈顶的时候,既是处于这种状态之下。

       

         PS:系统最不愿意回收处于运行状态下的Activity,因为这回给用户造成很糟糕的体验


  • 暂停状态:

        * 当一个Activity不再位于栈顶,但却又处于“用户可见”的状态下的时候,既是位于暂停状态。

       

        通常我们理解,一个Activity被另一个Activity“压栈”,而离开栈顶,既是有一个新的“界面视图”进入。

        那么什么时候一个Activity会出现不再位于栈顶,却又被用户可见的情况呢?

        Android中,并不是所有的活动都会占满整个屏幕,例如新压入栈顶的Activity是一个对话框形式的活动时,前一个Activity则会进入到这种所谓的暂停状态。


        暂停状态下的Activity无法响应用户的操作,但仍然是被用户可见的,所以系统仍然不愿意去回收此状态下的Activity。


  • 停止状态:

        * 当一个Activity不再位于栈顶,并且不再被“用户可见”的时候,就进入到了停止状态。


        PS:处于停止状态的活动最大的特点是:系统仍然为其保存相应的状态和成员变量,但这并不是绝对可靠的。

        这是因为位于该种状态下的Activity,在一些其他优先级更高的程序需要内存的时候,系统会选择回收释放掉该状态下的Activity,以提供足够的内存。


        所以,如果在你的某个Activity中,如果有一些该活动重新回到栈顶时,需要“重现”的数据的话,

        为了避免这种状态下的意外发生,可以选择在onSaveInstanceState()方法中保存信息,在下次活动恢复的时候从onCreate()方法中进行恢复,避免数据丢失。


  • 销毁状态:

        * 当一个活动从返回栈中被移除时,就处于销毁状态了。系统最倾向于回收这种活动,以保存手机内存的充足。


2、Activity的7种生命周期方法的理解

前面说到了所谓的四种活动状态,其实就是根据Android的生命周期的各个阶段的特点归纳出来的,所以我们自然也应该理解这7种生命周期的特点,它们分别是:

   - onCreate()
    * 在一个活动初次被创建时调用.    
    * 通常应该在这个方法里完成活动的初始化事件,如:加载布局,初始化控件,绑定事件等等..
    
   - onStart()
    * 在活动由不可见变为可见时调用.
    
   - onResume()
    * 当一个活动准备好和用户进行交互时进行调用。此时的活动一定位于返回栈的顶端,处于运行状态。
    
   - onPause()
    * 在系统准备去启动或恢复另一个活动的时候调用。
    * 通常在这个方法内将一些消耗CPU的资源释放,以及保存一些关键数据。
    * 但该方法内的内容执行速度一定要快,也就是说不要在此方法内做耗时操作,否则会影响新的栈顶活动的使用。
    
   - onStop()
    * 在活动完全不可见的时候调用。
    * 和onPause的调用特点类似,但最大的不同在于,例如:
       从当前活动启动的是一个对话框形式的Activity,onPause会得到调用,而onStop不会调用。

   - onRestart()
    * 这个方法在活动由停止状态变为运行状态之前调用,也就是重新启动。 
   
   - onDestroy()
    * 在活动即将被销毁之前调用,调用完毕后该活动进入销毁状态。
    


3、Activity生命周期图

为了更好的对Android中一个Activity在实际运行过程中,生命周期阶段变化的理解,我们结合官方的说明图加深印象。

Android - Acitivty生命周期 理解_第1张图片


从这张图中,我们可以归纳得到以下几种情况:

1、当一个Activity初次被创建时,会经过onCreate → onStart → onResume,此时该活动便已经压入栈顶,进入到了运行状态。


2、此时如果有另一个Activity来到前台,可分为我们上面说到的两种情况:

  • 新进入前台的是“对话框式”的Activity,此时onPause方法被调用,活动进入到暂停状态。而当活动再次返回时,直接调用onResume方法后恢复到运行状态。
  • 新进入前台的是普通的Activity,此时当前我们的Activity进入到不可见状态,经历onPause → onStop方法后,进入停止状态;若再次返回,则经历onRestart → onStart → onResume后,重新启动进入到运行状态。

3、在Activity执行onStop()方法进入到停止状态后,如果出现“另一个优先级更高的地方需要内存”的情况,进程被杀死,此时如果想要返回,则会重新经历onCreate → onStart → onResume的过程,从而恢复到运行状态。

4、当执行完onDestory方法后,Activity则会被系统销毁,进入到销毁状态之中了。


4、结合实际代码测试、加深理解
书止于此,理论上 我们对Android中Activity的生命周期已经有了一个较为全面的理解。
但我们不能满足于做一个书面上的巨人,于是我们通过实际的代码来对我们的理解进行一个验证,加深理解。

我们的大体思路是:
1、建立一个MainActivity,用于测试生命周期
2、建立一个普通的Activity,用于测试活动被覆盖进入到不可见状态下的生命周期方法执行情况。
3、建立一个对话框式的Activity,用于测试活动不挤出栈顶,但仍然可见下的情况下的生命周期情况。

根据我们的思路书写代码,首先是MainActivity:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class LifeCycleTestMainActivity extends Activity {

	private final String TAG = "LifeCycleTestMainActivity";
	private Button start_normal_activity;
	private Button start_dialog_activity;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Log.v(TAG, "onCreate...");
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.life_cycle_main_layout);

		// 恢复数据
		if (savedInstanceState != null) {
			String tempData = savedInstanceState.getString("tempData");
			// do something...
		}
		initView();
	}

	private void initView() {
		start_normal_activity = (Button) this.findViewById(R.id.start_normal_activity);
		start_dialog_activity = (Button) this.findViewById(R.id.start_dialog_activity);

		start_normal_activity.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(LifeCycleTestMainActivity.this, LifeCycleNormalActivity.class);
				startActivity(intent);

			}
		});

		start_dialog_activity.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(LifeCycleTestMainActivity.this, LifeCycleDialogActivity.class);
				startActivity(intent);

			}
		});

	}

	// 保存临时数据,避免活动进入到“停止状态”时,被系统回收,数据消失的问题
	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		String tempDate = "some temp data have need saved";
		outState.putString("tempData", tempDate);
	}

	@Override
	protected void onStart() {
		Log.v(TAG, "onStart...");
		super.onStart();
	}

	@Override
	protected void onResume() {
		Log.v(TAG, "onResume...");
		super.onResume();
	}

	@Override
	protected void onPause() {
		Log.v(TAG, "onPause...");
		super.onPause();
	}

	@Override
	protected void onStop() {
		Log.v(TAG, "onStop...");
		super.onStop();
	}

	@Override
	protected void onRestart() {
		Log.v(TAG, "onRestart...");
		super.onRestart();
	}

	@Override
	protected void onDestroy() {
		Log.v(TAG, "onDestroy...");
		super.onDestroy();
	}

}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/start_normal_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="start normal activity"
        android:textSize="20sp" />

    <Button
        android:id="@+id/start_dialog_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/start_normal_activity"
        android:text="start dialog activity"
        android:textSize="20sp" />
    

</RelativeLayout>

接着是NormalActivity与DialogActivity的类文件与布局文件,它们十分基本,只用于测试“activity跳转”时,MainActivity的生命周期变化情况,唯一需要记得就是,
为了让DialogActivity以对话框形式出现,我们再mainfest.xml文件中加以配置:
<activity android:name=".LifeCycleDialogActivity" android:theme="@android:style/Theme.Dialog"/>

搞定,接下来我们运行程序,进行测试:
1、首先是该程序初次运行时,我们查看log日志,得到:


结果与我们从第三部分的流程图中得出的结论一致,初次启动某个Activity时,经历了:onCreate → onStart → onResume。
从而进入到运行状态,一直处于可见状态下与用户进行交互。

2、直到我们点击了"start_normal_activity"按钮,于是normal activity进入前台,此时我们再次查看日志,得到:



日志打印的结果与我们总结的依旧一致,由于新的”NormalActivity“进入返回栈顶,并且"MainActivity"已经进入到不可见状态。
所以MainActivity此时尽力了:onPause →  onStop的过程,进入了停止状态。

3、此时我们点击回退键,返回MainActivity,再次查看日志:



OK,依旧如我们所想,MainActivity由停止状态恢复到运行状态,经历了:onRestart → onStart → onResume。

4、这次我们选择点击另一个按钮"start_dialog_activity",于是"DialogActivity"进入到栈顶,并且!MainActivity不再位于栈顶,但其仍然处于可见状态,让我们再次查看日志,看看发生了什么:



验证成功,由于MainActivity虽然不再位于栈顶,但其仍然处于可见状态,所以其经历的过程仅仅为:onPasue。


5、再次点击回退键,返回MainActivity,查看日志:



很高兴,依然与我们料想的一样,从暂停状态中恢复,我们只经历了一步:onResume.


6、我们已经位于我们的主界面"MainActivity",此时再次点击回退键,查看日志:


事实上,我们此时再次点击回退键的时候,我们最直观看到的就是:"屏幕返回到了系统的主界面"。
所以我们不难想到,MainActivity离开栈顶,并且进入了不可见的状态,它自然同样会经历:onPause →  onStop。
而与此同时,实际上这时离开栈顶的MainActivity实际上已经是位于返回栈中唯一的Activity了,
当一个程序的返回栈中已经没有任何活动,我们最通俗的理解也就是"我们已经退出该应用了"。
所以这个时候系统紧接着又执行了onDestroy方法,然后销毁掉了MainActivity。

至此,我们"理解完了Android中Activity的生命周期,退出了应用"。

你可能感兴趣的:(android,Activity生命周期)