今天繼續昨天的Activity lifecycle,再多看看其他的callbacks吧。一樣參考官網教學文的範例,在昨天的hello world程式碼裡加ㄧ些東西。
目標:
package com.example.hana.helloworld;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
static final String MY_STATE_STR = "MY_STATE_STR";;
static final String TEXT_VIEW_KEY = "TEXT_VIEW_KEY";
TextView mTextView; // 我新加的按鈕
String mStateStr; // 我新加的文字
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("[HANA_DEBUG]","In onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("[HANA_DEBUG]","Bundle:"+savedInstanceState); // 看看傳來的Bundle有沒有值
if (null != savedInstanceState) {
mStateStr = savedInstanceState.getString(MY_STATE_STR); // 也可移到onRestoreInstanceState()
Log.d("[HANA_DEBUG]","mStateStr:"+mStateStr);
}
mTextView = (TextView) findViewById(R.id.btn1); // 按鈕id,在activity_main.xml取名的
}
@Override
protected void onStart() {
Log.d("[HANA_DEBUG]","In onStart()");
super.onStart();
}
@Override
public void onResume() {
Log.d("[HANA_DEBUG]","In onResume()");
super.onResume();
}
@Override
public void onPause() {
Log.d("[HANA_DEBUG]","In onPause()");
super.onPause();
}
@Override
public void onStop() {
Log.d("[HANA_DEBUG]","In onStop()");
super.onStop();
}
@Override
public void onDestroy() {
Log.d("[HANA_DEBUG]","In onDestroy()");
super.onDestroy();
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) { // savedInstanceState不是null才會呼叫,所以不需null check
Log.d("[HANA_DEBUG]","In onRestoreInstanceState()");
mTextView.setText(savedInstanceState.getString(TEXT_VIEW_KEY)); // 更改按鈕文字吧
Log.d("[HANA_DEBUG]","mStateStr:"+mStateStr);
}
@Override
public void onSaveInstanceState(Bundle outState) { // 儲存Bundle,等等實驗看看哪時會被呼叫
Log.d("[HANA_DEBUG]","In onSaveInstanceState()");
outState.putString(MY_STATE_STR, "State: saving"); // 儲存name/value到Bundle
outState.putString(TEXT_VIEW_KEY, "Hi, I'm saving!"); // 儲存name/value到Bundle
Log.d("[HANA_DEBUG]","Bundle:"+outState); // 印看看是否成功儲存
super.onSaveInstanceState(outState);
}
}
Layout裡的activity_main.xml,我先加一個基本的文字按鈕(R.id.btn1)。現在還沒有其他功能,只是想先改變一下文字,所以我先給它一個default的文字,如下圖:
編譯完第一次執行,可以看到onCreate()先被呼叫,再來是onStart()。只是不知為何onResume()緊接著也被呼叫了。
按鈕文字還是default的,沒有被改變!
如下圖:
然後按一下Home鍵,onPause()被呼叫了,onSaveInstanceState()也被呼叫了,這樣我的資料就自動被存囉!緊接著,onStop()也被呼叫了,這也是比較不直覺的地方。
如下圖:
按一下右邊那顆鍵,確定我們的APP還在,如下圖:
然後把APP給砍了,這時onDestroy()會被呼叫。不過並不是每一次都會被呼叫,不知是我的Logcat太lag還是真的沒有被呼叫。
接著,我重新從APP選單裡啟動APP,預期onCreate()會被呼叫,Bundle裡應該要存東西,結果發現,onCreate()確實是被呼叫了,但Bundle是null!!
以結果來看,Bundle並不是永遠都存在,似乎會跟著APP一起生一起滅。所以要想一個不要真的砍掉APP,但卻可以重新呼叫onCreate()的方法。網路上查了一下,發現旋轉螢幕可以做到這件事,所以我就來旋轉一下我的螢幕,如下圖:
終於啊,預期的行為算是成功出現了!
旋轉螢幕之後,首先被呼叫的是onPause(),再來是onSaveInstanceState(),這時我把Bundle內容印出來,的確有成功存好。再來呼叫了onStop()、onDestroy(),緊接著的是onCreate(),這時候Bundle終於有東西了,而且內容跟存進去的時候不太一樣呢。接著呼叫onStart()、onRestoreInstanceState()、onResume(),完成旋轉螢幕的動作。
心得與疑問:
之後再來慢慢研究了。