【實作練習】Android Activity生命週期(Lifecycle)簡介與實作測試

仔細想想,Ray小編似乎從來沒有好好研讀過Android Activity的運作方式到底是怎麼一回事,在參考網上其他神人介紹Android Activity生命週期之後,Ray小編決定要來實作看看,究竟是否真是這樣運作?

首先先讓我們來看看Android Activity生命週期示意圖。由下面這張生命週期表,我們可以得知,Activity的生命週期主要有七個方法,分別是:
1. onCreate():分配資源給這個Activity,用來做初始化的動作,物件的宣告與設置都是在此撰寫。
2. onStart():將Activity內容顯示到螢幕上。
3. onResume():取得螢幕的控制權,在這個階段,用戶才能與Activity互動。同時,若開發者想要取得物件的長度、寬度等等屬性,也可以在此取得。
4. onPause():凍結原本的Activity,再交出直接存取螢幕能力。
5. onStop():Activity的運作完全停止。
6. onDestroy():銷毀Activity,釋放出資源。
7. onRestart():將凍結的Activity資源重新來拿使用。

關於onPause()與onStop(),我個人對於onPause()的解讀是,由於其他Activity要進行運作,所以要先交出螢幕存取的能力,其他Activity才能與用戶進行互動,但該Activity並沒有要進行銷毀,所以先進行凍結的動作。而關於onStop()的解讀則是,由於onPause()凍結的Activity生死未定,所以由onStop()負責等待決定要選擇重新啟用它或是銷毀它。


接下來到了實作的部分,Ray小編在這裡分別創了A Activity與B Activity,並分別做了七項實驗,分別是「剛開啟一個Activity時」、「A Activity跳到B Activity時」、「B Activity返回A Activity時」、「Activity結束時」、「按Home鍵時」、「再度返回原本的Activity時」以及「在執行B Activity時,直接將該App結束掉」。

1. 剛開啟一個Activity時
onCreate(A) > onStart(A) > onResume(A)
剛開啟一個Activity時,其運作流程為分配資源給這個Activity(onCreate()),接著將它顯示在螢幕上(onStart()),最後取得螢幕的控制權(onResume())。


2. A Activity跳到B Activity時
onPause(A) > onCreate(B) > onStart(B) > onResume(B) > onStop(A)
A Activity跳到B Activity時,會先凍結A Activity(onPause()),然後重複開啟一個Activity時的流程,最後停止A Activity,以待決定要將A Activity重啟或是銷毀(onStop())。


3. B Activity返回A Activity時
onPause(B) > onRestart(A) > onStart(A) > onResume(A) > onStop(B) > onDestroy(B)
B Activity返回A Activity時,B Activity會先被凍結(onPause()),接著是喚醒A Activity的資料(onRestart()),再來是照之前的流程,顯示A Activity內容到螢幕上(onStart())、取得螢幕控制權(onResume())、停止B Activity(onStop()),這裡不同的是B Activity因為沒有要再使用了,因此選擇銷毀(onDestroy())。


4. Activity結束時
onPause(A) > onStop(A) > onDestroy(A)
Activity結束時,會先凍結該Activity(onPause()),然後停止這個Activity(onStop()),最後銷毀它(onDestroy())。其實凍結(onPause())到停止(onStop())中間,同樣有去喚醒(onRestart())前一個Activity,也就是依然是照著第三個實驗步驟走,只不過這邊因為沒有Tag它,所以沒顯示出來。


5. 按Home鍵時
onPause(A) > onStop(A)
在A Activity執行時按Home鍵時的步驟,基本上與實驗四差不多,但是不同之處在於按Home時,因為尚未得知該App會被重新喚醒或是銷毀,因此只走到停止的階段(onStop())。


6. 再度返回原本的Activity時
onRestart(A) > onStart(A) > onResume(A)
再度回到原本的Activity時,其執行步驟與實驗三大同小異,一樣是喚醒該Activity(onRestart())、顯示(onStart())並取得螢幕控制權(onResume())。


7. 在執行B Activity時,直接將該App結束掉
onPause(B) > onStop(B) > onDestroy(A) > onDestroy(B)
在執行B Activity時,直接將該App結束掉,我們會發現B Activity會被凍結(onPause()),然後停止(onStop())等待決定自己的下場,而A Activity則是已在停止階段(onStop())待命。因為是將App整個結束掉,因此最後A Activity執行銷毀(onDestroy())的動作,B Activity也跟著執行銷毀(onDestroy())的動作,結束其短暫的一生。


以下是實驗時的編碼,首先是Layout的配置。
File Name:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Next Page" />
    <TextView
        android:id="@+id/txt"
        android:gravity="center"
        android:textSize="50dp"
        android:textStyle="bold"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

再來是Java編碼的部分。
File Name:AActivity public class AActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("1111", "A - onCreate()");
        TextView txt = (TextView) this.findViewById(R.id.txt);
        txt.setText("A");
        Button btn = (Button) this.findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(AActivity.this, BActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("1111", "A - onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("1111", "A - onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("1111", "A - onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("1111", "A - onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("1111", "A - onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("1111", "A - onRestart()");
    }
}

File Name:BActivity
public class BActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("1111", "B - onCreate()");
        TextView txt = (TextView) this.findViewById(R.id.txt);
        txt.setText("B");
        Button btn = (Button) this.findViewById(R.id.btn);
        btn.setVisibility(View.INVISIBLE);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("1111", "B - onStart()");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("1111", "B - onResume()");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("1111", "B - onPause()");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i("1111", "B - onStop()");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("1111", "B - onDestroy()");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("1111", "B - onRestart()");
    }
}

以下是實作結果。


最後Ray小編提供一下自己參考的文章中還不錯的文章,我個人是覺得這篇文章用詞簡單不會太艱深,寫得還挺清楚明瞭的,如果看完本篇還有疑慮的話,不妨去看看這位神人的介紹。
>> 點擊這裡 <<

對於onPause()與onStop()之間的差異,這篇文章也挺不錯的,推薦給大家。
>>點擊這裡<<

沒有留言:

張貼留言