2011/03/26

ホームボタン と 戻るボタン で Activity の終了処理が異なる

@Android 2.1 Xperia

Android の Activity は以下のようなライフサイクルを持っているというのは、大抵の本やサイトで紹介されています。(以下の図は Tech Booster さんから頂きました。大変わかり易いです)

ただ、「Activity がもう表示されない」という状態も
  • 戻るボタンで Activity が消える
  • ホームボタンで Activity が消える
  • 省電力モードになって画面が消える
  • 他のアプリケーションがかぶさって Activity が消える
といろいろなパターンがあります。
そして、最近気づいたのですが、これらのパターンで呼ばれるイベントが異なるようなのです。

以下、Xperia で動作させてみたときのログです。

起動
DEBUG/LifeCycleTest(3005): onCreate
DEBUG/LifeCycleTest(3005): onStart
DEBUG/LifeCycleTest(3005): onResume



戻るボタン
DEBUG/LifeCycleTest(3005): onPause
DEBUG/LifeCycleTest(3005): onStop
DEBUG/LifeCycleTest(3005): onDestroy



アイコンクリック
DEBUG/LifeCycleTest(3005): onCreate
DEBUG/LifeCycleTest(3005): onStart
DEBUG/LifeCycleTest(3005): onResume



ホームボタン
DEBUG/LifeCycleTest(3005): onSaveInstanceState
DEBUG/LifeCycleTest(3005): onPause
DEBUG/LifeCycleTest(3005): onStop



アイコンクリック
DEBUG/LifeCycleTest(3005): onRestart
DEBUG/LifeCycleTest(3005): onStart
DEBUG/LifeCycleTest(3005): onResume



時間がたって画面消灯
DEBUG/LifeCycleTest(3028): onSaveInstanceState
DEBUG/LifeCycleTest(3028): onPause



電源ボタン
DEBUG/LifeCycleTest(3028): onResume



画面回転
DEBUG/LifeCycleTest(3028): onSaveInstanceState
DEBUG/LifeCycleTest(3028): onPause
DEBUG/LifeCycleTest(3028): onStop
DEBUG/LifeCycleTest(3028): onDestroy
DEBUG/LifeCycleTest(3028): onCreate
DEBUG/LifeCycleTest(3028): onStart
DEBUG/LifeCycleTest(3028): onRestoreInstanceState
DEBUG/LifeCycleTest(3028): onResume



ハードウェアキーでカメラアプリ起動
DEBUG/LifeCycleTest(3028): onSaveInstanceState
DEBUG/LifeCycleTest(3028): onPause
DEBUG/LifeCycleTest(3028): onStop


戻るボタンで Activity が見えなくなる場合は onDestroy が呼ばれてアプリケーションが終了しているのに対し、ホームボタンの場合は onPause でサスペンド状態になるようです。
ユーザから見ると、どちらも同じ動作に見えるんですけどね。
また、単に画面が消える場合は onStop で止まるようです。

あと、 onSaveInstanceState と onRestoreInstanceState は呼ばれる時と呼ばれない時があるみたいです。これ、対になっていないと意味がないような気がするのですが…
この結果だけみると、あまり使い道が無いような気がします。
この辺については、もう少し調べてみる必要がありそうです。
誰か詳しい方がいらっしゃいましたら、是非教えてください。

2011/10/11 追記
「ユーザから見ると、どちらも同じ動作に見えるんですけどね」と書いたのですが、Androidの思想的には全然違う動作のようです。
ホームボタンを押した場合は、ホームアプリケーションが起動して現在のアプリケーションが後ろに隠れるだけなのに対し、戻るボタンはActivityスタックからポップするという動作になるようです。
Activityのスタックについては、Y.A.M の 雑記帳: Android Activity, Task, Stack, Launch mode が非常にわかりやすかったので、是非参考にしてみてください。


以下に、実際に動作させたコードを載せておきます。
単にイベントの中でログを出力させているだけです。

MainActivity.java
package com.kokufu.test.lifecycletest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

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

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Log.d(TAG, "onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();

        Log.d(TAG, "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();

        Log.d(TAG, "onResume");
    }

    @Override
    protected void onRestart() {
        super.onRestart();

        Log.d(TAG, "onRestart");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        Log.d(TAG, "onRestoreInstanceState");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        Log.d(TAG, "onSaveInstanceState");

        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause");

        super.onPause();
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop");

        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy");

        super.onDestroy();
    }
}

0 件のコメント: