フラグメントの状態の保存(フラグメント)

一般的な問題は、デバイスを回転させるときのアプリケーションの不正な動作です。 実際のところ、Activity-host(フラグメントの親であるActivity)を破棄すると破棄されます。 このプロセスが発生した瞬間、FragmentManagerは子フラグメントを破棄する責任があります。 FragmentManagerは、死にかけているフラグメントライフサイクルのメソッドonPause()onStop() 、およびonDestroy()を開始します。



たとえば、子フラグメントのコントローラーにMedia-Playerオブジェクトがある場合、フラグメントメソッドFragment.onDestroy()で、大音量で再生しているMedia-Playerのインスタンスがメディアデータの再生を中断します。 最初に頭に浮かぶのは、データを保存するFragment.onSaveInstanceState(Bundle)を呼び出してMedia-Playerオブジェクトの状態を保存することです。これにより、新しいアクティビティがデータをロードします。 ただし、 MediaPlayerオブジェクトの状態とその後の復元を保存すると、それでも再生が中断され、ユーザーの心に憎しみのサメが走り回ります。



フラグメントの保存



幸いなことに、フラグメントには、 Media-Playerのインスタンスが構成の変更を「 生き残る 」ことができるメカニズムがあります。 Fragment.onCreate(...)メソッドをオーバーライドし、fragmentプロパティを設定します。



@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRetainInstance(true); }
      
      





フラグメントのretainInstanceプロパティは、 デフォルトではfalseです。 つまり、デバイスの電源を入れると、フラグメントは保存されず、アクティビティホストとともに新しい方法で破壊および作成されます。 setRetainInstance(true)が呼び出されると、フラグメントはホストとともに破棄されず、変更されていない形式で新しいアクティビティに渡されます。 フラグメントを保存するとき、すべてのフィールド(Viewを含む)が以前の値を保持するという事実に依存できます。 私たちは彼らに目を向け、彼らはすでにそれを持っています。 このアプローチを使用すると、デバイスの電源を入れたときに、 MediaPlayerオブジェクトが再生を中断せず、ユーザーがフリークしないようにすることができます。



ターンと保存されたフラグメント



ここで、保存されたフラグメントがどのように機能するかを詳しく見る価値があります。 フラグメントは、フラグメント自体を破棄する必要なく、フラグメントの表現を破棄および再作成できるという事実に基づいています。 構成が変更されると、 FragmentManagerはフラグメントビューを破棄して再構築します。 アクティビティも同様に動作します。 これは、新しい構成では新しいリソースが必要になる可能性があるという考慮事項によるものです。 新しいバージョンにより適したリソースがある場合、プレゼンテーションはゼロから構築さます。



FragmentManagerは、各フラグメントのretainInstanceプロパティをチェックします。 デフォルト (false)の場合、FragmentManagerはフラグメントのインスタンスを破棄します。 フラグメントとそのビューは、新しいアクティビティに属するFragmentManagerの新しいインスタンスで再作成されます。



画像



retainInstancetrueの場合はどうなり ますか 。 フラグメントの表現は破棄されますが、フラグメント自体は残ります。 Activityの新しいインスタンスが作成され、保存されたFragmentを見つけてそのビューを再作成する新しいFragmentManagerが作成されます。



画像



保存されたフラグメントは前のアクティビティから切り離されて存続しますが、アクティビティホストはありません。



画像



したがって、保存された状態への移行は、次の条件が満たされると発生します。





この場合、 フラグメントは、最初のアクティビティから切断された瞬間から、すぐに作成された新しいActicvityに使用するために転送されるまで、それほど長く生きません。



フラグメントの保存:本当に良いですか?



保存されたフラグメント:本当に便利ですか? はい! 本当に快適です。 一見すると、彼らはターン中のアクティビティとフラグメントの破壊で生じるすべての問題を解決します。 デバイスの構成を変更して最適なリソースを選択すると、新しいビューが作成され、データとオブジェクトを保存する簡単な方法を自由に使用できます。



この場合、すべてのフラグメントを連続して保存しないのはなぜか、デフォルトでフラグメントが保存されないのはなぜですか? AndroidはUIにフラグメントを保存することに熱心ではないという印象を、思わず得ることができます。 なぜそうなのかははっきりしていません。

保存されたフラグメントは、アクティビティが破棄されたとき、つまり設定が変更されたときにのみ存在し続けることに注意してください。 OSがメモリを解放する必要があるためにアクティビティが破棄された場合、保存されたすべてのフラグメントも破棄されます。



onSaveInstanceState(バンドル)について話す時間です



このアプローチは、コーナリング時のデータ損失の問題を処理するのにより一般的です。 提案がこの状況を簡単に満たす場合、すべてはonSaveInstanceState(...)のデフォルトの動作によるものです。



onSaveInstanceState(...)メソッドは、アプリケーションのユーザーインターフェイスの状態の保存と復元を解決するために設計されました。 私が思うように、あなたはそれを推測しました-これらのアプローチの間には根本的な違いがあります。 Fragment.onSaveInstanceState(...)のオーバーライドとFragmentの保存の主な違いは、保存されているデータの期間です。



その場合、構成の変更中にデータをしばらく保存することを目的とする場合、フラグメントの保存に必要な作業は大幅に少なくなります。これは、オブジェクトの保存時に特に当てはまります。開発者はオブジェクトがSerializableを実装するかどうか心配する必要はありません。



ただし、データがより長く存在する必要がある場合は、フラグメントを保存しても役に立ちません。 ユーザーが非アクティブの後にActivityが破棄されてメモリが解放された場合、保存されたすべてのフラグメントは、未保存の親族と同じ方法で破棄されます。



結論として



そのため、アクティビティまたはフラグメントに長期間存在する必要があるデータが含まれる場合、アクティビティのライフタイムに関連付けonSaveInstanceState(Bundle)メソッドをオーバーライドして状態を保存し、後で復元する必要があります。



All Articles