Now you can Subscribe using RSS

Submit your Email

2016/09/01

Activity LifeCycle

asd

Activity 是Android 四大組件之首也是開發中最常見到,有關Activity 的生命週期可以大致分為七個部分



onCreate: Activity 正在被創建的時候會呼叫的方法,通常會在這方法中去做加載畫面UI的工作。

onStart: Activity 正在被啟動使用者還不能看到畫面的狀態。

onResume: Activity 已經可被使用者看見的狀態。

onPause: Activity 正在停止使用者還是可以看到畫面狀態,可以在這動作中做一點資料儲存動作但是不能太耗時間不然會影響下一個Activity的呈現 。

onStop: Activity 已經即將停止使用者已經看不到畫面。

onDestory: Activity 正在被銷毀,通常會做資源釋放比較大量的工作。

onRestart: Activity正在重新被啟動,當Activity從不可見轉變為可以看到的時候會呼叫這個方法。




有兩個方法比較特殊在Activity異常情況下會調用的方法


onSavsInstanceState: 會儲存當前Activity狀態,此方法會在onStop之前呼叫。

onRestoreInstanceState:會把Activity銷毀前所存進去 onSavsInstanceState 的資料重新恢復到Activity上。


可以看看以下的圖片會比較清楚整個流程





舉例說明一下


1. 當使用者第一次啟動畫面時會呼叫
         onCreate  > onStart > onResume。

2. 當使用者切換畫面或者從APP切換到桌面的時候當前的畫面會呼叫
         onPause  > onStop。

3. 當使用者從桌面要返回APP畫面時會呼叫
         onRestart  > onStart > onResume。

首先我們先建立一個專案


然後建立兩個Layout畫面裡面各放一個Button,一個放TextView一個放EditText
兩個Button Click事件分別Intent兩個畫面
Java檔程式內容都一樣分別TAG不一樣
以其中一個Java檔舉例

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    private Button btn_MainActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "調用 onCreate");

        btn_MainActivity = (Button) findViewById(R.id.btn_MainActivity);
        btn_MainActivity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "MainActivity onClick");
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, SecondActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d(TAG, "調用 onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "調用  onResume");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "調用 onStop");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "調用 onPause");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.d(TAG, "調用 onRestart");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "調用 onDestroy");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.d(TAG, "異常情況調用 onSaveInstanceState");
    }
    

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        Log.d(TAG, "異常情況調用 onRestoreInstanceState");
    }
}


Layout畫面如下




當APP第一次被啟動的時候看一下 Logcat 上的資訊,可發現符合 例1 的舉例




再來模擬 例2 ,按下 Button 後 Logcat 顯示如下



可以發現當畫面要被切換的時候一開始的Activity會先執行 onPause 後,新Activity才會執行onStart,符合文章前面介紹所說的 onPasue 可進行一些資源的儲存動作但不能太耗時,不然會影響新Activity畫面的執行。


接下來模擬 例2 另一種情況  我們直接按下手機上的首頁按鈕。



可以發現畫面切換的時候確實是先執行 onPasue 後再執行 on Stop。


最後模擬 例3 畫面 我們從首頁上直接返回原本APP畫面。




因為回到手機桌面的時候 SecondActivity 只是執行了 onStop,所以重新返回APP時是呼叫了 onRestart 而不是呼叫 onCreate 重新建立畫面,這個預期符合生命週期圖片上所描述。


接下來模擬異常情況的發生


onSaveInstanceState 文章上面有敘述 會在onStop 之前調用,但實際上跑上面的Code 按下Button 會發現以下情況。



調用了 onSaveInstanceState 但是卻沒有調用到 onRestoreInstanceState 這是為什麼呢,從文章開頭有說過他會把目前Activity 的狀態存進去 onSaveInstanceState  然後 onRestoreInstanceState  是恢復Activity資訊,由於按下Button是切換到新的Activity所以不需要舊的Activity資訊故沒有呼叫出 onRestoreInstanceState  。


那要如何呼叫出 onRestoreInstanceState  ?
舉一個簡單例子讓畫面翻轉。



可以發現要呼叫出 onRestoreInstanceState   必須是當前 Activity 發生設定上改變或是畫面上的變動,才會呼叫此功能 會把畫面上的資訊在 onResume 之前也就是使用者可以看見畫面之前重新把資訊部屬好。

onSaveInstanceState  所儲存的資訊像是 Edit 已經填寫的內容與 Text 的顯示文字,當發生異常情況的時候存進去最後再呼叫 onRestoreInstanceState   把資訊全部都補回來。

程式碼下載 :GitHub

0 意見:

張貼留言

Coprights @ 2016, Blogger Templates Designed By Templateism | Templatelib