Android – Activity運作模式

基本觀念

在應用程式開發領域中的生命週期的觀念, 指的是與一般生物的生命過程類似的過程. 當一個人從出生開始, 就自動地進入到嬰兒時期, 而隨著時間的推進, 逐步進入到兒童, 少年, 青年, 中年及老年的階段. 這樣的演進, 並非你我可以任意改變, 但是你我都可以規劃在特定的時期, 將會進行特定的任務. 同樣的道理, 在Android中的Activity也是具有類似的生命週期的觀念, 當一個Activity被啟動之後, 就將會逐步執行onCreate(), onStart()以及onResume()方法之後, 進入到執行時期等等類似的生命週期的觀念.

先看到橢圓形的圖示, 表示一個Activity所處的模式, 灰色方塊的圖示, 表示呼叫的方法. 對於使用者的角度而言, 看到的是狀態的改變; 開發者則是面對狀態的改變, 去開發設計方法. 

重點是去設計開發方法的內容, 而不是去呼叫這些方法, 因為如同上述的觀點, 不會因為去呼叫 onStart() 之後, 就重新進入 Running 狀態的

觀察Activity的生命週期

以單一的Activity為範例來詳細了解其生命週期. 首先, 依照上圖中的矩形圖示開發撰寫Override.

 

import android.util.Log;

public class MainActivity extends AppCompatActivity {

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

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

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

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

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

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

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

 

在個別的onXxx()方法中, 分別加上了Log.d(標籤字串,訊息字串); 的敘述句, 用來透過Logcat來監視當時的現狀, 標籤字串通常由開發者自訂即可, 而訊息字串則是用來觀察當時的執行狀況.

再度執行專案到模擬器上面, 並將Logcat視窗開啟, 並使其在Logcat頁籤模式下, 並設定Log紀錄的過濾器:

這樣就可以方便在Logcat終只針對自訂的 tag 來觀察其變化.

實驗以下狀況:

  • 啟動執行狀態後直接按下返回
  • 啟動執行狀態 –> Home –> Icon
  • 啟動執行狀態 –> Menu
  • 手機橫豎變更

作完實驗之後, 可以簡單的歸納一下

  1. onCreate() 只會在啟動之後被執行一次
  2. onStart() 與 onResume() 是在啟動後被執行一次, 之後每此的 onRestart()之後被執行
  3. 當離開前景狀態時, 則會進入 onPause() 與 onStop()
  4. 當再度返回前景的程序, 則是 onRestart(), onStart() 與 onResume()
  5. 手機橫豎變更將會重新 onCreate()
  6. 好玩的是, 什麼情況下會是由 onPause() 再回到 onResume(), 這部分在官方網站有提到, 請參考: https://developer.android.com/training/basics/activity-lifecycle/pausing.html?hl=zh-tw

仔細讀過一遍, 應該不是那麼容易了解, 將會在這一篇<Android – 暫停繼續的生命週期>說明詳細狀況.

而當手機橫豎變換時, 將會由 onStop() 將原先的 Activity 呼叫 onDestroy(), 而且還會由 onStop() 直接呼叫 onCreate(), 這是一個很重要的特性.

目前為止都是由<返回>鍵離開 Activity. 而如果想要透過程式中決定離開的時間, 則應該呼叫 finish().

事實上, 也可以 Override finish(), 如下:

    @Override
    public void finish() {
        super.finish(); // 註解之後無法離開,或是返回 ==> 此為真正的離開點呼叫
    }

通常會在呼叫 super().finish(); 敘述句之前, 進行離開前要做的敘述句.

很常見的應用, 就是按下離開或是<返回>鍵, 因為擔心是使用者的誤動作, 而出現一個 Toast 訊息, 要求再按一下已確認離開的行為. 當然, 如果第二次的觸發行為不能間隔太久, 否則視為下一次的動作. 實作如下: (間隔時間為3秒內)

 

package tw.brad.fsit_activity_lifecycle;

import android.annotation.SuppressLint;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private long lastClickExit = 0;

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

    public void test1(View view) {
        finish();
    }

    @Override
    public void finish() {
        //super.finish(); // 註解之後無法離開,或是返回 ==> 此為真正的離開點

        long nowClickExit = System.currentTimeMillis();
        if (lastClickExit == 0 || nowClickExit - lastClickExit >= 3*1000){
            lastClickExit = nowClickExit;
            Toast.makeText(this, "one more exit", Toast.LENGTH_SHORT).show();
        }else {
            super.finish();
        }
    }
}

 

%d bloggers like this: