web-dev-qa-db-ja.com

アクティビティ内でフラグメントバックスタックを復元する方法(アプリケーションがバックグラウンドで強制終了された後)

Android app-

私がActivity-MyActivityにいて、一度に1つのFragmentを保持しているとします。

最初にロードしましたフラグメントA(タグなしでFragmentManagerのバックスタックに追加しました)

次に、ある時点でロードしましたフラグメントB(タグなしでFragmentManagerのバックスタックに追加しました)

次に、ある時点でロードしましたフラグメントC(タグなしでFragmentManagerのバックスタックに追加しました)

popBackStack()を使用して戻るボタンの動作を有効にしているので、フラグメントCから戻ると、フローは次のようになります。

フラグメントC-> フラグメントB-> フラグメントA-> 閉じるMyActivity..

すべてが完璧です :-)

しかし、私がフラグメントCにいて、アプリがバックグラウンドで強制終了された場合([設定]から[アクティビティフラグを保持しない]を使用しました)

およびオンラインに戻るフラグメントCMyActivityにロードされます

ただし、FragmentManagerのバックスタックにはフラグメントC。のみが含まれます。

戻るボタンがめちゃくちゃです

フラグメントC-> MyActivityを閉じる..

なぜそうなのですか?

FragmentManager内のActivityのバックスタックを適切に復元するにはどうすればよいですか?

14
Arun C

ルートアクティビティで alwaysRetainTaskState を使用してみてください。 Androidは、アプリを使用してから長い時間が経過し、ユーザーが最初からやり直したいと考えているため、アクティビティのバックスタックを自動的にクリアします。

 <activity Android:alwaysRetainTaskState="true"/>

この設定により、その動作が防止され、その動作がフラグメントマネージャーに継承される可能性があります。

9
shredder

アプリの開発中に、アクティビティの復元/保存された状態、ADBを使用したフラグメントをテストすることをお勧めします。

  1. アプリを開く
  2. アクティビティ間を移動する
  3. プレスホーム
  4. ADB->アプリを強制終了(停止)
  5. アプリケーションスタック(デバイスのメニューボタン)を押して、アプリケーションを再開します

このようにして、保存/復元状態をデバッグできます。

複雑なアプリケーションがない場合は、アクティビティで保存/復元状態を処理することをお勧めします。

private Fragment1 mFragment;

@Override
protected void onCreate(Bundle savedState) {
   super.onCreate(savedState);
   // ...

   if (savedState == null) {
       mFragment = new Fragment1();

       getFragmentManger().beginTransacation().add(mFragment, TAG).addToBackStack(TAG).commit();
   }
   else {
       mFragment = getFragmentMananager().findFragmentByTag(TAG);
   }
}

複数のFragmentsまたはViewPagerまたはネストされたフラグメントがある場合、事態は非常に複雑になる可能性があります。アプリケーション全体を再起動することをお勧めします。

@Override
protected void onCreate(Bundle savedState) {
   super.onCreate(savedState);

   if (savedState != null) {
      Intent intent = new Intent(ActivityMain.this, ActivityMain.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
      startActivity(intent);

      return;
   }
}

保存/復元の各状態を処理する場合は、次の投稿をお読みください: http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

4

この方法を試してください

public void setRetainInstance (boolean retain)

フラグメントインスタンスをアクティビティの再作成(構成の変更など)全体で保持するかどうかを制御します。これは、バックスタックにないフラグメントでのみ使用できます。設定されている場合、アクティビティが再作成されると、フラグメントのライフサイクルはわずかに異なります。

開発者のウェブサイトから http://developer.Android.com/reference/Android/app/Fragment.html#setRetainInstance%28boolean%29

1
Moinkhan

フラグメントCは、アプリケーションの停止後にロードしないでください。アプリケーションに初期フラグメントがありますか?理想的には、フラグメントのポップを実装するときは、初期化画面が必要です。アプリケーションがメモリの理由で停止または強制終了された場合、アプリケーションはフラグメントA(Init Fragment)から開始する必要があります。フラグメントCからではありません。

問題でこの解決策が必要な場合は、新しいフラグメントが先頭に来たときに、各フラグメントを永続的に保存する必要があります。これは理想的には、これを達成するためにプリファレンスまたはデータベースにバックスタックを永続化することを意味します。

0
user1649464