iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
自我挑戰組

Android API超初學!!系列 第 22

[Android API] [Day 22] Activity lifecycle (2) - Bundle/Other callbacks

今天繼續昨天的Activity lifecycle,再多看看其他的callbacks吧。一樣參考官網教學文的範例,在昨天的hello world程式碼裡加ㄧ些東西。

目標:

  • 昨天說的六個主要callbacks,到底哪時候會被呼叫呢?
  • 在Bundle裡存ㄧ些東西
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的文字,如下圖:
https://ithelp.ithome.com.tw/upload/images/20181101/20112439vA7imr3K0H.jpg

編譯完第一次執行,可以看到onCreate()先被呼叫,再來是onStart()。只是不知為何onResume()緊接著也被呼叫了。
按鈕文字還是default的,沒有被改變!
如下圖:
https://ithelp.ithome.com.tw/upload/images/20181101/20112439BdDBYkLcCy.jpg

然後按一下Home鍵,onPause()被呼叫了,onSaveInstanceState()也被呼叫了,這樣我的資料就自動被存囉!緊接著,onStop()也被呼叫了,這也是比較不直覺的地方。
如下圖:
https://ithelp.ithome.com.tw/upload/images/20181101/201124393OgzTMUQfF.jpg

按一下右邊那顆鍵,確定我們的APP還在,如下圖:
https://ithelp.ithome.com.tw/upload/images/20181101/20112439qqF5PeWLDg.jpg

然後把APP給砍了,這時onDestroy()會被呼叫。不過並不是每一次都會被呼叫,不知是我的Logcat太lag還是真的沒有被呼叫。
接著,我重新從APP選單裡啟動APP,預期onCreate()會被呼叫,Bundle裡應該要存東西,結果發現,onCreate()確實是被呼叫了,但Bundle是null!!

以結果來看,Bundle並不是永遠都存在,似乎會跟著APP一起生一起滅。所以要想一個不要真的砍掉APP,但卻可以重新呼叫onCreate()的方法。網路上查了一下,發現旋轉螢幕可以做到這件事,所以我就來旋轉一下我的螢幕,如下圖:
https://ithelp.ithome.com.tw/upload/images/20181101/20112439tQbrbZHpqz.jpg

終於啊,預期的行為算是成功出現了!
旋轉螢幕之後,首先被呼叫的是onPause(),再來是onSaveInstanceState(),這時我把Bundle內容印出來,的確有成功存好。再來呼叫了onStop()、onDestroy(),緊接著的是onCreate(),這時候Bundle終於有東西了,而且內容跟存進去的時候不太一樣呢。接著呼叫onStart()、onRestoreInstanceState()、onResume(),完成旋轉螢幕的動作。

心得與疑問:

  • 原來旋轉螢幕的effort這麼大
  • Bundle到底存在哪?
  • 為什麼我的layout會跑掉啊?

之後再來慢慢研究了。
/images/emoticon/emoticon06.gif


上一篇
[Android API] [Day 21] Activity lifecycle (1) - onCreate
下一篇
[Android API] [Day 23] Activity lifecycle (3) - Callback and State
系列文
Android API超初學!!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言