在介绍Activity的生命周期之前,我们先来了解一下Activity的几种状态。Android针对Activity的管理使用的是栈,就是说某一个时刻只有一个Activity处在栈顶,当这个Activity被销毁后,下面的 Activity才有可能浮到栈顶,或者有一个新的Activity被创建出来,则旧的Activity就被压栈沉下去了。Activity是直接涉及到与用户交互的界面处理的,而任意时刻与用户处于交互状 态的界面只能有一个,所以Android针对Activity的管理采用了具有层次感的栈的数据结构,理解这一点对于Activity一些状态转换的细节 处理非常重要。

依据这种基于界面层次性的理解,官方文档主要提了两点:

1、只有处于栈顶的Activity一定是出于运行状态的。当启动一个新的Activity时,系统会将它置于栈顶,同时使其运行,这个时候先前处于栈顶的Activity则被压栈,只有当栈顶的Activity退出时才可能重新处于栈顶。

2、在Android中,Activity拥有四种状态:

(1)、活动(激活)状态  (Active/Runing)     一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的 激活状态。

(2)、暂停状态 (Paused)  此时它在屏幕上仍然是可见的,但是失去了焦点。这种情况会发生在当有一个不会占满整个屏幕或者拥有透明属性的Activity启动并获得了屏幕焦点时。一个暂停状态的Activity还是存活的(alive),它仍然维持着自己的各个内部状态和成员信息,仍然和window manager保持连接,但是系统可能会在手机内存极低的情况下杀掉该Activity;

(3)、终止状态 (Stop) 此时这个Activity在屏幕上完全不可见,它已经被其他的Activity挡住了。这时它维持着自己的各个内部状态和成员信息,但是由于用户已完全看不见它,其window也会被隐藏掉,也就是说window manager不再管理其window信息了。停止状态下的Activity会经常由于手机的内存征用问题被系统杀掉。

(4)、销毁状态 (Killed) Activity 被系统杀死回收或者没有被启动时处于 Killed状态

如果一个Activity被暂停或停止,系统可以将它从内存移除,通过要求它结束(通过调用它的finish()方法),或简单地杀掉它的进程。当它再次显示给用户时,必须要完全重新启动和恢复到之前的状态。在 android.app.Activity类中,Android 定义了一系列与生命周期相关的方法,在我们自己的 Activity 中,只是根据需要复写需要的方法:

public class Activity extends ApplicationContext {
	     protected void onCreate(Bundle savedInstanceState);
	     protected void onStart();
	     protected void onRestart();
	     protected void onResume();
	     protected void onPause();
	     protected void onStop();
	     protected void onDestroy();
	 }

Activity在不同状态之间相互转换时,与调用的方法如下图:

Activity生命周期
Activity生命周期

下面我们就通过一个Demo来帮助大家更好的理解上面那张图。

1、新建一个Android项目ActivityDemo,并新建一个Activity命名为MainActivity

New Android Project
New Android Project

2、在main.xml中添加三个按钮,分别跳转到SecondActivity、DialogActivity、和结束MainActivity

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center_vertical" >
     <!-- 添加三个按钮,分别跳转到第二个Activity、DialogActivity、和finish()该Activity -->
     <Button
        android:id="@+id/btn_SecondActivity"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_text_SecondActivity"/>
	  <Button
        android:id="@+id/btn_DialogActivity"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_text_DialogActivity"/>
	   <Button
        android:id="@+id/btn_Finish"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_text_finish"/>
 </LinearLayout>

3、再新建两个Activity:SecondActivity和DialogActivity,布局文件分别为:second.xml和dialog.xml second.xml,添加一个TextView控件,显示:我是SecondActivity

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center_vertical" >
     <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tip_secondActivity"
        android:gravity="center_horizontal"/>
 </LinearLayout>

 

dialog.xml,添加一个TextView控件和Button控件,TextView显示我是DialogActivity,Button显示确定

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center_vertical" >
     <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tip_DialogActivity"
        android:gravity="center_horizontal"/>
     <Button
        android:id="@+id/btn_Ok"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/btn_text_Ok"/>
 </LinearLayout>

 

SecondActivity.java代码如下,重写上面提到的生命周期的几个方法并添加日志打印,方便我们观察。

package com.liuzhichao.activity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class SecondActivity extends Activity {

	private static final String TAG="ActivityDemo";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		Log.i(TAG, "SecondActivity--onCreate()");
	}

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

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

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

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

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

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

}

DialogActivity.java:重写生命周期的几个方法,当点击确定按钮后,结束该Activity

package com.liuzhichao.activity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class DialogActivity extends Activity {
	private static final String TAG="ActivityDemo";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.dialog);
		Log.i(TAG, "DialogActivity--onCreate()");
		Button btn_Ok = (Button)findViewById(R.id.btn_Ok);
		btn_Ok.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				DialogActivity.this.finish();
			}
		});
	}

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

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

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

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

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

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

}

4、MainActivity.java中的代码如下:点击相应的按钮时,处理相应的事件。

package com.liuzhichao.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	private static final String TAG="ActivityDemo";

	private Button btn_secondActivity;
	private Button btn_DialogActivity;
	private Button btn_Finish;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		Log.i(TAG, "MainActivity--onCreate()");

		findViews();
		setListeners();
	}

	/**
	 * 绘制界面
	 */
	private void findViews(){
		btn_secondActivity = (Button)findViewById(R.id.btn_SecondActivity);
		btn_DialogActivity = (Button)findViewById(R.id.btn_DialogActivity);
		btn_Finish	=(Button)findViewById(R.id.btn_Finish);
	}

	/**
	 * 设置按钮处理事件
	 */
	private void setListeners(){
		/**
		 * 点击btn_secondActivity时跳转到SecondActivity
		 */
		btn_secondActivity.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(MainActivity.this, SecondActivity.class);
				startActivity(intent);
			}
		});

		/**
		 * 点击btn_DialogActivity时跳转到DialogActivity
		 */
		btn_DialogActivity.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(MainActivity.this, DialogActivity.class);
				startActivity(intent);
			}
		});

		/**
		 * 点击btn_Finish时关闭MainActivity
		 */
		btn_Finish.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				MainActivity.this.finish();
			}
		});
	}

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

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

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

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

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

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

5、最后不要忘了在AndroidManifest.xml注册新建的Activity

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liuzhichao.activity"
    android:versionCode="1"
    android:versionName="1.0" >

     <uses-sdk android:minSdkVersion="8" />

     <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
         <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <!-- 注册 SecondActivity-->
         <activity android:name=".SecondActivity"/>

         <!-- 注册 DialogActivity 并让其以对话框的样式显示-->
         <activity android:name=".DialogActivity"
                  android:theme="@android:style/Theme.Dialog"/>
     </application>

 </manifest>

同时,项目中使用的string.xml内容如下:

<?xml version="1.0" encoding="utf-8"?>
 <resources>
     <string name="hello"> Hello World, MainActivity! </string>
     <string name="app_name"> ActivityDemo </string>
	 <string name="btn_text_SecondActivity"> 点我跳到SecondActivity </string>
	 <string name="btn_text_DialogActivity"> 点我跳到DialogActivity </string>
	 <string name="btn_text_finish"> finish() </string>
	 <string name="tip_secondActivity"> 我是SecondActivity </string>
	 <string name="tip_DialogActivity"> 我是DialogActivity </string>
	 <string name="btn_text_Ok"> 确定 </string>
 </resources>

6、运行项目

查看LogCat的打印,在系统调用了onCreate和onStart之后,调用了onResume,自此,Activity进入了运行状态。

提示:如果你的控制台没有显示LogCat,Window–ShowView–Android–LogCat

7、点击跳转到第二个Activity按钮,当界面跳转到第二个Activity后

查看LogCat的打印:

8、我们点击模拟器的返回按键,返回到MainActivity,再查看LogCat的打印:

9、点击跳转到DialogActivity

查看LogCat的打印:

10、点击DialogActivity上的确定按钮结束DialogActivity再查看LogCat的打印:

11、这时我们先不点击结束按钮,我们点击模拟器上的Home键返回主菜单,再查看LogCat的打印:

12、我们再从模拟器上点击ActivityDemo直接运行程序,查看LogCat的打印:

13、最后我们再点击finish() 结束MainActivity,再查看LogCat的打印:

总结:

1、Activity生命周期中的各个方法与Activity状态的关系

  • onCreate()       Activity创建时被调用
  • onStart()          Activity创建或者从后台重新回到前台时被调用
  • onRestart()      Activity从后台重新回到前台时被调用
  • onResume()    Activity界面可与用户交互时调用
  • onPause()        Activity被覆盖到下面或者失去焦点无法与用户交互时被调用
  • onStop()          Activity被完全覆盖或者跳转到新Activity时被调用
  • onDestroy()    Activity被销毁时被调用

2、Activity的完整生命周期、可视生命周期、前台生命周期

  • Activity的整个生命时间,从第一次调用onCreate()开始直到调用onDestroy()结束。一个活动在onCreate()中做所有的”全局”状态的初始设置,在onDestroy()中释放所有保留的资源。举例来说,有一个线程运行在后台从网络上下载数据,它可能会在onCreate()中创建线程,在onDestroy()中结束线程。
  • Activity的可视生命时间,从调用onStart()到相应的调用onStop() 。在这期间,用户可以在屏幕上看见活动,虽然它可能不是运行在前台且与用户交互。在这两个方法之间,你可以保持显示活动所需要的资源。举例来说,你可以在onStart()中注册一个广播接收者监视影响你的UI的改变,在onStop()中注销。因为活动在可视和隐藏之间来回切换onStart()和onStop()可以调用多次。
  • Activity的前台生命时间,从调用onResume()到相应的调用onPause()。在这期间,频繁地在重用和暂停状态转换——例如,当设备进入睡眠状态或一个新的活动启动时调用onPause(),当一个活动返回或一个新的意图被传输时调用onResume()。因此,这两个方法的代码应当是相当轻量级的。

Activity的生命周期与程序的健壮性有着密不可分的关系,希望朋友们能够认真体会、熟练应用。下一讲,我们将讲解Activity横竖屏时Activity的生命周期情况。