看过android API 的筒子都知道,Activity的API中有大量的onXXXX形式的函数定义,除了我们前面用到的onCreate以外,还有onStart,onStop以及onPause等等。从字面上看,它们是一些事件回调,那么次序又是如何的呢?其实这种事情,自己做个实验最明白不过了,在相应的activity中加入Log输出,从而看看activity的生命周期是怎么变化的。
创建两个activity,ActivityA和ActivityB,从ActivityA界面上的按钮可以跳到ActivityB(两个activity可以一样,通过TAG来进行区分),以下为相关代码:
界面布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ActivityA" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_below="@+id/textView1"
android:layout_marginLeft="20dp"
android:layout_marginTop="25dp"
android:text="Button" />
</RelativeLayout>
ActivityA:
package com.example.activitylifecycle;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityA extends Activity {
public final static String TAG = "ActivityA";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activity);
Log.i(TAG, "onCreate");
Button button = (Button) this.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent it = new Intent(ActivityA.this, ActivityB.class); //启动activityB
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(it);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity, menu);
return true;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
Log.i(TAG, "onDestory");
super.onDestroy();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
Log.i(TAG, "onPause");
super.onPause();
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
Log.i(TAG, "onRestart");
super.onRestart();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
Log.i(TAG, "onResume");
super.onResume();
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
Log.i(TAG, "onStart");
super.onStart();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
Log.i(TAG, "onStop");
super.onStop();
}
}
ActivityB:
package com.example.activitylifecycle;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ActivityB extends Activity {
public final static String TAG = "ActivityB";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_activityb);
Log.i(TAG, "onCreate");
Button button = (Button) this.findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity, menu);
return true;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
Log.i(TAG, "onDestory");
super.onDestroy();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
Log.i(TAG, "onPause");
super.onPause();
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
Log.i(TAG, "onRestart");
super.onRestart();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
Log.i(TAG, "onResume");
super.onResume();
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
Log.i(TAG, "onStart");
super.onStart();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
Log.i(TAG, "onStop");
super.onStop();
}
}
以下为输出的日志信息:
//启动activityA 过程
06-21 22:44:45.867: I/ActivityA(5775): onCreate
06-21 22:44:45.867: I/ActivityA(5775): onStart
06-21 22:44:45.867: I/ActivityA(5775): onResume
//启动activityB,ActivityA隐藏于后台
06-21 22:45:01.417: I/ActivityA(5775): onPause
06-21 22:45:01.587: I/ActivityB(5775): onCreate
06-21 22:45:01.587: I/ActivityB(5775): onStart
06-21 22:45:01.587: I/ActivityB(5775): onResume
06-21 22:45:02.027: I/ActivityA(5775): onStop
//按返回键
06-21 22:45:12.967: I/ActivityB(5775): onPause
06-21 22:45:12.987: I/ActivityA(5775): onRestart
06-21 22:45:12.987: I/ActivityA(5775): onStart
06-21 22:45:12.987: I/ActivityA(5775): onResume
06-21 22:45:13.107: I/ActivityB(5775): onStop
06-21 22:45:13.117: I/ActivityB(5775): onDestory
//按home键
06-21 22:45:21.997: I/ActivityA(5775): onPause
06-21 22:45:22.287: I/ActivityA(5775): onStop
//从图标重新进入activityA 06-21 22:48:30.187: I/ActivityA(5775): onRestart
06-21 22:48:30.187: I/ActivityA(5775): onStart
06-21 22:48:30.187: I/ActivityA(5775): onResume
从日志可以清楚的看出activity的整个生命周期的变化过程,以下从android官方文档上的对各个生命周期的详细解释:
1. void onCreate(Bundle savedInstanceState)
当Activity被第首次加载时执行。我们新启动一个程序的时候其主窗体的onCreate事件就会被执行。如果Activity被销毁后 (onDestroy后),再重新加载进Task时,其onCreate事件也会被重新执行。注意这里的参数 savedInstanceState(Bundle类型是一个键值对集合,大家可以看成是.Net中的Dictionary)是一个很有用的设计,由于 前面已经说到的手机应用的特殊性,一个Activity很可能被强制交换到后台(交换到后台就是指该窗体不再对用户可见,但实际上又还是存在于某个 Task中的,比如一个新的Activity压入了当前的Task从而“遮盖”住了当前的 Activity,或者用户按了Home键回到桌面,又或者其他重要事件发生导致新的Activity出现在当前Activity之上,比如来电界面), 而如果此后用户在一段时间内没有重新查看该窗体(Android通过长按Home键可以选择最近运行的6个程序,或者用户直接再次点击程序的运行图标,如 果窗体所在的Task和进程没有被系统销毁,则不用重新加载Process, Task和Task中的Activity,直接重新显示Task顶部的Activity,这就称之为重新查看某个程序的窗体),该窗体连同其所在的 Task和Process则可能已经被系统自动销毁了,此时如果再次查看该窗体,则要重新执行 onCreate事件初始化窗体。而这个时候我们可能希望用户继续上次打开该窗体时的操作状态进行操作,而不是一切从头开始。例如用户在编辑短信时突然来 电,接完电话后用户又去做了一些其他的事情,比如保存来电号码到联系人,而没有立即回到短信编辑界面,导致了短信编辑界面被销毁,当用户重新进入短信程序 时他可能希望继续上次的编辑。这种情况我们就可以覆写Activity的void onSaveInstanceState(Bundle outState)事件,通过向outState中写入一些我们需要在窗体销毁前保存的状态或信息,这样在窗体重新执行onCreate的时候,则会通过 savedInstanceState将之前保存的信息传递进来,此时我们就可以有选择的利用这些信息来初始化窗体,而不是一切从头开始。
2. void onStart()
onCreate事件之后执行。或者当前窗体被交换到后台后,在用户重新查看窗体前已经过去了一段时间,窗体已经执行了onStop事件,但是窗 体和其所在进程并没有被销毁,用户再次重新查看窗体时会执行onRestart事件,之后会跳过onCreate事件,直接执行窗体的onStart事 件。
3. void onResume()
onStart事件之后执行。或者当前窗体被交换到后台后,在用户重新查看窗体时,窗体还没有被销毁,也没有执行过onStop事件(窗体还继续存在于Task中),则会跳过窗体的onCreate和onStart事件,直接执行onResume事件。
4. void onPause()
窗体被交换到后台时执行。
5. void onStop()
onPause事件之后执行。如果一段时间内用户还没有重新查看该窗体,则该窗体的onStop事件将会被执行;或者用户直接按了Back键,将该窗体从当前Task中移除,也会执行该窗体的onStop事件。
6. void onRestart()
onStop事件执行后,如果窗体和其所在的进程没有被系统销毁,此时用户又重新查看该窗体,则会执行窗体的onRestart事件,onRestart事件后会跳过窗体的onCreate事件直接执行onStart事件。
7. void onDestroy()
Activity被销毁的时候执行。在窗体的onStop事件之后,如果没有再次查看该窗体,Activity则会被销毁。