在学习Android的生命周期前,我们应该知道Android是使用任务来管理活动(Activity)的。一个任务就是存放在栈里的活动的集合。因为栈是一种后进先出的数据结构,因此,当我们启动了一个新的活动,它就会被置于栈顶,而原先的活动就会被压入栈中。当我们按下Back键或调用finish()方法后,前一个入栈的活动就会被重新置于栈顶。处于栈顶的活动就是显示给用户的活动。
活动的状态
一个活动最多可以有四种状态:
1、运行状态
处于运行状态的活动就是当前显示给用户的活动并且和用户交互的活动,这个活动也是位于栈顶的活动。
2、暂停状态
处于暂停状态的活动仍然是可见的,这一点和运行状态的活动一样。不过,暂停状态的活动不位于栈顶,并且不能和用户交互。这儿可能不好理解,意思是在活动(A)上方有一个新的活动(B),并且这个新的活动(B)没有占满整个屏或者新的活动是透明的时候,下方的活动(A)就会处于暂停状态。
3、停止状态
当活动不处于栈顶,并且完全不可见的时候,它就处于停止状态,系统在内存不足的时候,有可能回收处于停止状态的活动。
4、销毁状态
当一个活动从栈中移除之后,它就变成了销毁状态了。系统一般会回收处于销毁状态的活动,从而保证内存充足。
当Activity从一种状态转变到另一种状态的时候,会调用一下的方法。
1、onCreate()
这个方法会在活动第一次被创建的时候调用,通常会在这个方法中进行一些初始化的操作。
2、onStart()
调用了这个方法之后,活动就是可见的了,但是它不一定是位于栈顶。。
3、onResume()
这个方法被调用后,活动就位于栈顶,可以和用户进行交互了。
4、onPause()
当系统要打开一个新的活动的时候,上一个活动就会调用这个方法,使得上一个活动处于暂停状态。
5、onStop()
在新的活动完全占满屏幕的时候,上一个活动完全不可见的时候调用这个方法。当新的活动只是占屏幕一部分的时候则只会调用onPause()方法,而不会调用onStop()方法。
6、onDestory()
在活动被销毁前调用,用于将活动转变成销毁状态。
7、onRestart()
这个方法是在处于停止状态活动重新被调用,转变为运行状态的时候调用,调用了这个方法之后,活动也就被重新启动了。
在Android中又可以将活动分为三种生命周期。
1、完整生命周期
处在onCreate()与onDestory()方法之间,就是一个完整生命周期。从各种数据的初始化,到最后释放所占用的内存资源。
2、可见生命周期
处在onStart()与onStop()方法之间,在这个生命周期中的活动是对用户可见的。在这个生命周期中可以通过onStart()和onStop()方法对资源进行加载和释放。
3、前台生命周期
处在onResume()与onPause()之间的就是前台生命周期,在这个周期中的活动总是处于运行状态,并且可以和用户交互的。
附经典的生命周期图:
之后再来说说生命周期的几个调用过程,假设有两个活动:活动A、活动B。
1、首先,创建活动A的时候。方法的调用过程:onCreate() ——> onStart() ——>onResume()。
2、在活动A上创建活动B的时候。首先,活动A会调用onPause()方法;接着活动B调用:onCreate() ——> onStart() ——>onResume();之后,活动A调用onStop()方法进入停止状态。
3、在活动B中按下Back键后,活动B会调用onPause()方法;接着调用活动A的onRestart() ——> onStart() ——>onResume();之后,活动B调用onStop()方法 ——> onDestory()方法,活动进入销毁状态。
4、在用户退出当前活动是,方法的调用顺序是onPause() ——>onStop() ——>onDestory()。
主界面的页面布局,非常简单,只有一个Button用于跳转页面:
<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"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/btnnext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="跳转到下一个Activity" />
</RelativeLayout>
主界面的功能实现:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private static String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
setContentView(R.layout.activity_main);
Button btn1 = (Button)findViewById(R.id.btnnext);
btn1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, BActivity.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(TAG, "onStart()");
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i(TAG, "onRestart()");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(TAG, "onResume()");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(TAG, "onPause()");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(TAG, "onStop()");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
第二个页面的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是第二个Activity" />
</LinearLayout>
第二个页面的功能实现:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class BActivity extends Activity {
private static String TAG = "BActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
setContentView(R.layout.bactivity);
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i(TAG, "onStart()");
}
@Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.i(TAG, "onRestart()");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i(TAG, "onResume()");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i(TAG, "onPause()");
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i(TAG, "onStop()");
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
之后,还需要在AndroidManifest对BActivity进行配置:<activity android:name=".BActivity"> </activity>
临时数据保存
当程序有可能被意外Destroy的时候, 例如在屏幕旋转时候的Activity销毁与重建, 还有在按下Home键或者屏幕黑屏等Activity处于Pause状态, 有可能被系统回收的时候。 默认情况下, 系统使用Bundle实例来保存每一个视图对象中的信息(例如输入EditText中的文本内容)。 如果要保存更多额外的数据, 就需要重写onSavedInstanceState(Bundle outState)方法保存数据,数据以键值对的形式保存。
这样,当你的Activity重建的时候, 系统就会将Bundle传递给你, 在onCreate()与onRestoreInstanceState() 回调方法都接收到了同样的Bundle,里面包含了同样的实例状态信息,再做相应的恢复就可以了。
在Activity中保存临时数据:
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
String tempData = "Hello World !";
outState.putString("key_data", tempData);
}
获取数据:
@Override
protected void onCreate(Bundle savedInstanceState){
if(savedInstanceState != null){
String tempData =savedInstanceState.getString("key_data");
Log.d("savedData", tempData);
}
}
<span style="font-size:18px"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;"></span></span></span></span><pre name="code" class="java"><span style="font-size:14px;"> @Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i("MainActivity", "onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
String tempData = savedInstanceState.getString("key_data");
Log.i("savedData", tempData);
}</span>
从下图可以看出onSaveInstanceState()和onRestoreInstanceState()的执行顺序: