web-dev-qa-db-ja.com

アクティビティが強制終了されて再作成された後もフラグメントは残ります

FragmentActivity(Support Fragments)があり、コードでフラグメントを作成し、FrameLayoutsに配置します。これまでのところ、すべて正常に機能しています。これで、アプリを終了しても、システムがアクティビティを強制終了しない限り、すべてが正常に返されます(または、DDMSの停止ボタンを使用して終了します)。それが起こった場合、何も呼び出されず、私のアクティビティは強制終了されます。 onDestroyは呼び出されません。

そのため、アプリを再度開くと、すべてのフラグメントがまだ存在し、作業を実行しようとするためにNullPointerExeptionsが表示されます。フラグメントはアプリのこの状態では存在しないはずなので、それは私にとって問題です。

私はそれらをbackStackに必要としないので、そこに配置せず、popBackStack()を呼び出してそれらを取り除くことはできません。

OnCreate()でFragmentManagerをリセットするにはどうすればよいですか、またはフラグメントも破棄されるようにするにはどうすればよいですか?

25
Towlie288

フラグメントの lifecycle はアクティビティのライフサイクルに似ているため、他のアプリのメモリを節約するために、システムによって強制終了および再作成できます。これは、フラグメントの状態を保存および復元するためのメカニズムがあることを意味します。あなたはそれを使うべきです。

  • フラグメントの状態を onSaveInstanceState に保存します
  • 状態を復元します-savedStateバンドルは複数のメソッドでフラグメントに提供されます( onCreateonCreateView など)

フラグメントの状態を保存できない場合(データが動的でシリアル化できないため)、初期化されていない状態に対してデフォルトの動作を実装してみてください。

4
stan0

これは実際には正常である可能性があります。多くのフラグメントをインスタンス化して破棄する代わりに、Androidがフラグメントを保持している可能性があります。これは、特にViewPagersで発生します。

多くのgetActivity()呼び出しを使用していますか、それともコンテキストを取得する呼び出しを使用していますか?もしそうなら、nullは次のような簡単なことをしてgetActivity()呼び出しをチェックします

Activity activity = getActivity();
if ( activity == null )
{
   Log.w("activity null!", "This will cause a crash if you access this variable!");
}

もう1つのヒントは、AsyncTasksに注意することです。これらのいずれかがバックグラウンドで実行されている場合は、アクティビティが生きているか死んでいるかを追跡する必要があります。 Androidの新しいバージョンにはライフサイクルチェックが組み込まれていると思いますが、onAttach()とonDetach()でブールフラグを保持することもできます。

3
Joe Plante

私はそれが本当に遅いことを知っていますが、私は同じ問題を抱えており、ここで答えを見つけました

サポートFragmentPagerAdapterは古いフラグメントへの参照を保持します

そしてここ

ViewPagerとフラグメント—フラグメントの状態を保存する正しい方法は何ですか?

問題は、アクティビティを作成するときに、フラグメント管理ではなく、いくつかのリストにフラグメントを作成して保存することだと思います。アクティビティが再度作成されると、フラグメントも作成されますが、フラグメントマネージャーは以前に作成されたフラグメントを使用します。このフラグメントは、アプリをバックグラウンドに置く前に作成されたフラグメントであるため、getActivity()に対してフラグメントがnullを返すのはそのためです。

2
mishasrb

同じ問題かどうかはわかりませんが、しばらく前に、ビューページャーのフラグメントに問題があり、フラグメントライフサイクルメソッドが呼び出されず、フラグメントマネージャーに問題がありました。

したがって、supportFragmentManagerの代わりにchildFragmentManagerを使用してみて、問題が解決するかどうかを確認してください。

0
Mikel