13

Android API のドキュメントによると、Activity.onRetainNonConfigurationInstance()はFragment.setRetainInstance()を支持して廃止されました。

ただし、Fragment.setRetainInstance() を使用できないと思われる 2 つの状況に遭遇しました。

  1. フラグメントに WebView が含まれている場合。Diane Hackborneによると、構成の変更後に WebView を再利用することはできません。これは、画面が回転したときに Fragment が WebView を破棄して再作成できるようにし、WebView.saveState()WebView.restoreState()を使用して Web ビューの状態を復元できるようにする必要があることを意味します。

  2. Fragment が、構成の変更後に存在しなくなったレイアウトに属している場合、FragmentManager が Fragment を復元しようとすると、以下がスローされます。

    java.lang.IllegalArgumentException: No view found for id 0x7f060091 for fragment
    

    これは、(たとえば) 横向きモードで 2 フラグメントのレイアウトがあり、縦向きモードで 1 つのフラグメントのレイアウトがある場合に発生する可能性があります。横向きから縦向きに回転するとき、setRetainInstance() が true に設定されている場合、どちらの Fragment も破棄されませんが、1 つのフラグメントに再アタッチする有効なビューがなくなるため、例外が発生します。

そのため、フラグメントベースのアプリケーションを構築していて、構成の変更間でデータ (実行中の AsyncTasks への参照など) を保持する必要があり、Fragment.setRetainInstance()を使用できず、 Fragment.onRetainNonConfigurationInstance がない場合()、とるべき最善のアプローチは何ですか?

4

2 に答える 2

0

私の質問に対する回答がないように見えますが、最終的に私がやったことは次のとおりです。

  1. 復元が必要なWebViewを含むFragmentの場合、 Fragment.onSaveInstanceState(Bundle state)をオーバーライドし、 WebView.saveState(bundle)を呼び出します。次にFragment.onViewCreated(View view, Bundle savedInstanceState)で、 savedInstanceStateが null でない場合はwebView.restoreState(savedInstanceState)を呼び出します。

  2. 保持する必要があるライブAsyncTasksを含むFragmentの場合、 Fragment.onDestroy()をオーバーライドして、それらのタスクを Application オブジェクトに保存します。(代わりに、それらを静的変数に格納することもお勧めします)。次に、Fragment.onCreate(Bundle savedInstanceState)で、それらのタスクが null でないかどうかを確認し、そうであれば復元します。(それが意味することはアプリに依存しますが、私の場合、 AsyncTaskの完了時にFragmentで呼び出されるようにコールバックを復元します)。

これが最善の解決策かどうかはわかりませんが、私が抱えていた問題に対処しているようです。

それでも、私はこの状況全体がややこしいと思います( onSaveInstanceState()onRetainNonConfigurationInstance()、およびonDestroy()を区別し、各シナリオで何を保存する必要があるかを決定します)。

于 2012-08-02T05:48:04.337 に答える