チュートリアル - アクティビティの状態を保存する
アクティビティ ライフサイクル ガイドで、状態の保存の根拠となる理論について説明しました。ここでは、例を見てみましょう。
アクティビティ状態のチュートリアル
ActivityLifecycle_Start プロジェクトを開いて、ビルドし、実行してみましょう。 これは非常にシンプルなプロジェクトで、アクティビティ ライフサイクルとさまざまなライフサイクル メソッドの呼び出し方法を示す 2 つのアクティビティがあります。 アプリケーションを起動すると、次の MainActivity
画面が表示されます。
状態遷移の表示
このサンプルの各メソッドは、アクティビティの状態を示すために IDE アプリケーション出力ウィンドウに書き込みます。 (Visual Studio で出力ウィンドウを開くには、「CTRL-ALT-O」と入力します。Visual Studio for Mac で出力ウィンドウを開くには、[表示] > [パッド] > [アプリケーション出力] の順にクリックします)。
アプリが最初に起動すると、出力ウィンドウにアクティビティ A の状態の変更が表示されます。
[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume
[アクティビティ B の開始] ボタンをクリックすると、アクティビティ B の状態が変更される間、アクティビティ A が一時停止および停止することがわかります。
[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.SecondActivity] Activity B - OnCreate
[ActivityLifecycle.SecondActivity] Activity B - OnStart
[ActivityLifecycle.SecondActivity] Activity B - OnResume
[ActivityLifecycle.MainActivity] Activity A - OnStop
その結果、アクティビティ B が開始され、アクティビティ A の代わりに表示されます。
[戻る] ボタンをクリックすると、アクティビティ B が破棄され、アクティビティ A が再開されます。
[ActivityLifecycle.SecondActivity] Activity B - OnPause
[ActivityLifecycle.MainActivity] Activity A - OnRestart
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume
[ActivityLifecycle.SecondActivity] Activity B - OnStop
[ActivityLifecycle.SecondActivity] Activity B - OnDestroy
クリック カウンターの追加
次に、クリックされた回数をカウントして表示するボタンが表示されるように、アプリケーションを変更します。 まず、次の MainActivity
にインスタンス変数 _counter
を追加しましょう。
int _counter = 0;
次に、Resource/layout/Main.axml レイアウト ファイルを編集し、ユーザーがボタンをクリックした回数を表示する新しい clickButton
を追加します。 その結果生成される Main.axml は、次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/mybutton_text" />
<Button
android:id="@+id/clickButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/counterbutton_text" />
</LinearLayout>
MainActivity
の OnCreate メソッドの末尾に次のコードを追加しましょう。このコードでは、clickButton
からクリック イベントを処理します。
var clickbutton = FindViewById<Button> (Resource.Id.clickButton);
clickbutton.Text = Resources.GetString (
Resource.String.counterbutton_text, _counter);
clickbutton.Click += (object sender, System.EventArgs e) =>
{
_counter++;
clickbutton.Text = Resources.GetString (
Resource.String.counterbutton_text, _counter);
} ;
アプリをビルドしてもう一度実行すると、新しいボタンが表示され、クリックするたびに _counter
の値がインクリメントされて表示されます。
ただし、デバイスを横モードに回転すると、このカウントは失われます。
アプリケーションの出力を調べると、アクティビティ A が一時停止し、停止し、破棄され、再作成され、再起動された後、縦モードから横モードへの回転中に再開されたことがわかります。
[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.MainActivity] Activity A - OnStop
[ActivityLifecycle.MainActivity] Activity A - On Destroy
[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume
アクティビティ A はデバイスの回転時に破棄されて再作成されるため、インスタンスの状態は失われます。 次に、インスタンスの状態を保存して復元するコードを追加します。
インスタンスの状態を保持するコードの追加
インスタンスの状態を保存するメソッドを MainActivity
に追加しましょう。 アクティビティ A が破棄される前に、Android は自動的に OnSaveInstanceState を呼び出し、インスタンスの状態を格納するために使用できるバンドルを渡します。 これを使用して、クリック数を整数値として保存しましょう。
protected override void OnSaveInstanceState (Bundle outState)
{
outState.PutInt ("click_count", _counter);
Log.Debug(GetType().FullName, "Activity A - Saving instance state");
// always call the base implementation!
base.OnSaveInstanceState (outState);
}
アクティビティ A が再作成されて再開されると、Android はこの Bundle
を OnCreate
メソッドに戻します。 OnCreate
にコードを追加して、渡された Bundle
から _counter
の値を復元しましょう。 clickbutton
が定義されている行の直前に次のコードを追加します。
if (bundle != null)
{
_counter = bundle.GetInt ("click_count", 0);
Log.Debug(GetType().FullName, "Activity A - Recovered instance state");
}
アプリをもう一度ビルドして実行し、2 番目のボタンを数回クリックします。 デバイスを横モードに回転しても、カウントは保持されます。
出力ウィンドウを確認して、何が起こったかを見てみましょう。
[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.MainActivity] Activity A - Saving instance state
[ActivityLifecycle.MainActivity] Activity A - OnStop
[ActivityLifecycle.MainActivity] Activity A - On Destroy
[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - Recovered instance state
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume
OnStop メソッドが呼び出される前に、新しい OnSaveInstanceState
メソッドが呼び出され、_counter
の値が Bundle
に保存されます。 Android は OnCreate
メソッドを呼び出したときにこの Bundle
を戻し、それを使用して _counter
の値を元の場所に復元できました。
まとめ
このチュートリアルでは、アクティビティ ライフサイクルに関する知識を使用して状態データを保持しました。