今日は、Xamarinでアクティビティの状態を管理(保持および復元)する方法を見ていきます。Androidアプリケーションは、設定/状態の変更のためのアプリの一貫性と反応性を維持するために。
目次
アクティビティの状態を保持して復元するのはなぜですか?
私はすでにAndroidの活動についての私の記事で説明したように、OSはいくつかの”一定の”状態の変化に反応するかもしれませんactivityの寿命の間にlifecycleメソッ ただし、Androidアプリには、設定が変更される可能性のある動作がいくつかあり、その後、アクティビティの状態(配置、UI要素、チェックボックスの選択など)が適切に処理されないと失われる可能性があります。
あなたに本当の例を与えるために:MoneyBackアプリケーションでは、二つのタブを持つメイン画面があります。 私は2番目のタブが選択されているときに気づいた:

MoneyBack–2番目のタブが選択されている
デバイスが回転しています:


moneyback–回転後に選択された1番目のタブ
最初のタブが選択されます。 ユーザーは自分の入力を失っています(2番目のタブの選択)。
画面の向きの変更は、私たちが活動の状態を保存し、復元することを気にする必要がある理由の一つです。
状態の変更を維持する–OnSaveInstanceState()
各アクティビティは、現在のアクティビティが強制終了されるとき(例えば、デバイスの画面の向きが変更されてい特定のアクションが発生したときにOSによって常に呼び出されるOnPause()やOnStop()のような、Activity Lifecycleメソッド(ここで既に説明しました)と混同しないでください。 OnSaveInstanceState()メソッドは、一般的にOnPause()の後とOnStop()の前に呼び出されますが、必ずしもそうではありません。 たとえば、ユーザーがActivityBからActivityyaに戻ったときには、ActivityBは決して強制終了されないため、まったく呼び出されません。 詳細については、公式のAndroidドキュメントを参照してください。
Onsaveinstancestate()はBundleパラメータを指定して呼び出されます。 これは追加でシリアル化される単純なキーと値の辞書を表しているので、文字列、整数などの単純な値を格納するために使用する必要があります。 状態変更イベントに関するより複雑なデータを格納するための他の構造と手法があります(この記事の「概要」セクションのリンクを参照)。
現在選択されているタブを保存するために、我々は次のようにメソッドを実装することができます。
OnSaveInstanceState(outState);
でホストされているcsは、各画面の向きの変更によりこのメソッドが呼び出され、選択したタブのインデックスが”selectedTabPosition”キーの下のBundle outState辞書に保
状態の変更を復元する–OnRestoreInstanceState()
考慮されたアクティビティがライフに戻る(再開されている)とすぐに、ONRESTOREINSTANCESTATE(Bundle savedInstanceState)メソッドがOSによって呼び出されます。 以前にOnSaveInstanceState()メソッドを呼び出して保存されたインスタンスがある場合にのみ呼び出されます。 これは、アクティビティの状態を保存するために使用したのと同じキーと値のシリアル化された辞書です。
タブ選択の復元の場合、次のコードが示すようにこのメソッドを実装できます:
previouslySelectedTabPosition変数は、”selectedTabPosition”キーの下に保存されたバンドル辞書の整数値、またはキーに保存されていない場合はデフォルト値(0)で初期化
注意:Onrestoreinstancestate()で提供されるBundleパラメータは、アクティビティの作成時に呼び出されるOnCreate(Bundle bundle)メソッドで利用可能なものとまったく同じです。 実際にはそこに保存された値を取得することもできますが、多くの場合、状態を復元するには(以前に選択したタブを選択するなど)、いくつかのUI要素 そのため、一般的なルールとしてOnRestoreInstanceState()を使用してActivityの状態を復元することをお勧めします(もちろん、例外的なケースがある場合があります)。 OnRestoreInstanceState()は常にOnCreate()の後に呼び出されます。さらに、OnCreate()メソッドでBundleパラメータを使用する場合は、bundleがNULLでないかどうかを毎回確認する必要があります(OnSaveInstanceState()が以前に呼び出されたかどうかがわからな
その結果、MoneyBackのMainActivityでデバイスを回転させた後でも、以前と同じタブが選択されます:

MoneyBack–回転時にタブを選択したままにする
Android OSで処理される”自動”状態の変更
androidアプリケーションでは、すべてのUI要素を”手動で”処理する必要があるわけではないことに気づいたかもしれませんその状態を保存するために、上記のメソッドを実装することで、その状態を保存する。 Androidは、基本的なUI要素の状態の何らかの「自動」保存と復元を実行します。ここでのルールは、UI要素(TextViewやButtonなど)にandroid:idが設定されている限りです。axmlレイアウトファイル、OSは自動的にそれらの要素の状態(例えばEditTextに入力されたテキスト)を管理します。
たとえば、そのように宣言されたEditTextの場合:
そのプロパティ(特にそのTextプロパティ)は自動的に保存され、画面の向きの変更に復元されます。
Summary
設定の変更(画面の向きの変更、いくつかのリソースを解放するためにOSによって強制終了されるアクティビティなど)によって引き起こ)OnSaveInstanceState()およびOnRestoreInstanceState()を実装することにより、Bundle serialized dictionaryとの間でキー値データを追加および取得しました。 これらのメソッドは常に呼び出されるわけではないことを覚えておく必要があります(たとえば、”戻る”ボタンを使用してアクティビティ間を移動す
レイアウトファイルで定義されたandroid:idを持つUIコントロールは、設定変更に耐性のある状態を持っています(Android OSによって自動的に処理されます)。
Bundle dictionaryは、パフォーマンスとメモリ使用率を向上させるためにシリアル化されているため、単純な型の値(文字列や整数など)のみを格納する必要があ より複雑なデータを保存するために、Androidはそれを管理するさまざまな可能性を提供します(たとえば、OnRetainNonConfigurationInstanceを使用)。