Android菜鳥的成長筆記(14)—— Android中的狀態保存探究(上)

我們在用手機的時候可能會發現,即使應用被放到後臺再返回到前臺數據依然保留(比如說我們正在玩遊戲,突然電話來瞭,當接完電話遊戲繼續玩),某些應用甚至會保留你離開時候的狀態及數據,這些原理是什麼?怎麼去實現這樣的應用?這將是我們這一篇文章要解開的問題。

有一句很常見的代碼如下,很多人不知道為什麼要加這麼一句話

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}

super.onCreate(savedInstanceState)中的saveInstanceState是什麼東西,為什麼我們必須給onCreate方法返回一個Bundle對象呢?

打開官網關於Activity的介紹:https://developer.android.com/guide/components/activities.html

我們會看到如下一個圖:

這幅圖就是Activity狀態保存過程,從圖中可以看到,如果其他Activity在該Activity之前就會調用onSaveInstanceState()方法,下面我們就來重載該方法看一下。vcD48cD48cHJlIGNsYXNzPQ==”brush:java;”>package com.example.myfirstapp;

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

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(“大碗幹拌”, “調用瞭onCreate方法”);
setContentView(R.layout.activity_main);
}

@Override
protected void onSaveInstanceState(Bundle outState) {
Log.i(“大碗幹拌”, “調用瞭SaveState方法”);
super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(“大碗幹拌”, “調用瞭RestoreState方法”);
super.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onDestroy() {
Log.i(“大碗幹拌”, “調用瞭onDestroy方法”);
super.onDestroy();
}

@Override
protected void onPause() {
Log.i(“大碗幹拌”, “調用瞭onPause方法”);
super.onPause();
}

@Override
protected void onRestart() {
Log.i(“大碗幹拌”, “調用瞭onRestart方法”);
super.onRestart();
}

@Override
protected void onResume() {
Log.i(“大碗幹拌”, “調用瞭onResume方法”);
super.onResume();
}

@Override
protected void onStart() {
Log.i(“大碗幹拌”, “調用瞭onStart方法”);
super.onStart();
}

@Override
protected void onStop() {
Log.i(“大碗幹拌”, “調用瞭onStop方法”);
super.onStop();
}
}

原來當activity進程被系統殺掉後再重新啟動的時候會調用onCreate()方法和onRestoreInstanceState()方法將onSaveInstanceState()保存的Bundle對象傳遞過來,現在明白前面的super.onCreate(savedInstanceState)的作用瞭,是恢復Activity的狀態數據。

運行後打印Log如下:

當我調至停止狀態時(手機屏幕關掉):

可以看到調用瞭SaveState方法,當我恢復的時候(手機屏幕打開)

我們再看看如果直接殺死進程(kill)後,打印的Log

看看官方對onRestroeState的解釋:

This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

從官方說明中可以看出,如果系統認為該Activity存在被系統收回(銷毀)的危險,比如說stop()狀態,則系統會調用onSaveInstanceState(Bundle)方法保存當前狀態,如果該Activity是正常主動銷毀則不會調用該方法。

下面是之間按手機上的BACK鍵,打印的Log

有如下幾種情系統會調用onSaveInstanceState方法:

1、按HOME鍵

2、長按HOME鍵選擇其他程序

3、按下電源(關閉屏幕)

4、啟動另一個新的Activity

5、切換屏幕方向

另外官方還提到,onSaveInstanceState和onRestoreInstanceState不一定是成對出現的,例如:先按下HOME再長按HOME回到該Activity打印的Log如下

雖然是這樣能保存狀態數據,這個是系統為我們Activity狀態保存提供的一個機制,但是通常我們再開發的時候可能會有目的的去保存一些數據,這樣我們可以將該數據在onStop()方法中保存。

下面我們再來證明onCreate()方法中的Bundle savedInstanceState參數是onSaveInstanceState中保存的值:

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		Log.i("大碗幹拌", "調用瞭SaveState方法");
		outState.putString("dawanganban", "歡迎關註大碗幹拌的CSDN博客");
		
		super.onSaveInstanceState(outState);
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.i("大碗幹拌", "調用瞭onCreate方法");
		//正常啟動時值為null
		if(savedInstanceState != null){
			Log.i("大碗幹拌", "onCreate方法中獲取的值為:" +
					savedInstanceState.getString("dawanganban"));
		}
		setContentView(R.layout.activity_main);
	}

打印的Log

發佈留言