web-dev-qa-db-ja.com

Android)でフラグメントの回復を防ぐ

フラグメントを使用しているため、アクティビティが再作成されたときにフラグメントを自動的に回復する必要はありません。ただし、Android Activity::onCreate(Bundle savedInstanceState)-> super.onCreate(savedInstanceState)が呼び出されるたびに、フラグメントにsetRetainInstance(false)を使用しても、フラグメントが復元されます。

さらに、それらではFragmentsFragment.performCreateView()は、Fragment::onAttach()などを経由せずに直接呼び出されます。さらに、復元されたFragment ..内の一部のフィールドはnullです。

Androidがフラグメントを復元しないようにする方法を知っている人はいますか?

P.S.構成変更のためにアクティビティを再作成する場合は、マニフェストandroid:configChanges="orientation|screenSize|screenLayoutに追加することで実行できることがわかっています。しかし、自動メモリクリーニングの場合にアクティビティを再作成するのはどうですか?

32
goRGon

アクティビティに追加して終了しました:

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

アクティビティの作成/再作成サイクルで保存されたデータを抑制し、フラグメントの自動再作成を回避します。

42
goRGon

@goRGonの回答は私にとって非常に役に立ちましたが、再作成後にアクティビティに転送する必要のある情報がさらにある場合、そのような使用は深刻な問題を引き起こします。

これは「フラグメント」のみを削除し、他のすべてのパラメータを保持する改良版です。

バンドルから削除されたIDは、Android.support.v4.app.FragmentActivityフィールドとしてFRAGMENTS_TAGクラスの一部です。もちろん、時間の経過とともに変化する可能性がありますが、予期されていません。

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

/**
 * Improve bundle to prevent restoring of fragments.
 * @param bundle bundle container
 * @return improved bundle with removed "fragments parcelable"
 */
private static Bundle createBundleNoFragmentRestore(Bundle bundle) {
    if (bundle != null) {
        bundle.remove("Android:support:fragments");
    }
    return bundle;
}
14
Menion Asamm

受け入れられた回答に記載されているこの方法を使用したときにViewPagerでNPEを取得した人は、オーバーライドしてください

ViewPager.onRestoreInstanceState(Parcelable state)

メソッドと呼び出し

super.onRestoreInstanceState(null);

代わりに。

2
Robin

アクティビティのonCreateでフラグメントを削除しました。

1
Kai

TransactionTooLargeExceptionに問題がありました。ありがたいことに、 tolargetool を使用した後、フラグメント(Android:support:fragments)がメモリ内にあり、トランザクションが大きくなりすぎていることがわかりました。それで、ついに私はこれをしました、そしてそれはうまくいきました。

@Override
public void onSaveInstanceState(final Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putSerializable("Android:support:fragments", null);
}
1
MontDeska

ViewPagerもあったので、fragmentManangerにフラグメントが含まれているかどうかを確認し、onCreate()で削除しました。

たとえば、このスレッドを使用します: コンテナからすべてのフラグメントを削除します

_FragmentManager fm = getSupportFragmentManager();
for (Fragment fragment: fm.getFragments()) {
  fm.beginTransaction().remove(fragment).commitNow();
}
_

commitNow()は、フラグメントを同期的に削除します。

0
mortalis