web-dev-qa-db-ja.com

フラグメントはすでにIllegalStateExceptionを追加しました

コンテナアクティビティでこのメソッドを使用して、BFragを表示します

public void showBFrag()
{
    // Start a new FragmentTransaction
    FragmentTransaction fragmentTransaction = mFragmentMgr.beginTransaction();

    if(mBFrag.isAdded())
    {
        Log.d(LOG_TAG, "Show() BFrag");
        fragmentTransaction.show(mBFrag);   
    }
    else
    {
        Log.d(LOG_TAG, "Replacing AFrag -> BFrag");
        fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);
    }

    // Keep the transaction in the back stack so it will be reversed when backbutton is pressed
    fragmentTransaction.addToBackStack(null);

    // Commit transaction
    fragmentTransaction.commit();        
}

コンテナのアクティビティから呼び出します。初めて:

  • elseステートメントに入り、mBFragがmAFragを置き換えます。

次に、戻るボタンを押します。

  • 操作が逆になります(mAFragは表示されますが、mBFragは削除されますか?)。

次に、同じアクティビティからshowBFrag()を呼び出して、先に進みます。

  • そして、elseステートメントに再び入ります。 (したがって、mBFragは追加されていないと推測できます)
  • しかし、私はフラグメントはすでにIllegalStateExceptionを追加しました ...を得ました(それではなぜifステートメントに入れなかったのですか?)

そう:

  1. フラグメントが既に追加されたIllegalStateException?を受け取っている場合、isAdded()メソッドがTRUEを返さないのはなぜですか?
  2. PopBackStack操作は、以前に追加されたフラグメントを完全に削除しますか?
  3. 私はどのような行動を誤解していますか?

編集:ここに例外の完全な情報があります。

06-07 12:08:32.730: ERROR/AndroidRuntime(8576): Java.lang.IllegalStateException: Fragment already added: BFrag{40b28158 id=0x7f0c0085}
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at Android.app.BackStackRecord.doAddOp(BackStackRecord.Java:322)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at Android.app.BackStackRecord.replace(BackStackRecord.Java:360)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at Android.app.BackStackRecord.replace(BackStackRecord.Java:352)
06-07 12:08:32.730: ERROR/AndroidRuntime(8576):     at myPackageName.containerActivity.showBFrag() // This line: "fragmentTransaction.replace(R.id.operation_fragments_frame, mBFrag);"
53
Axel M. Garcia

最後に、私の回避策は、前のフラグメントのremove()を実行し、新しいフラグメントをadd()することです。 replace()method が意図したことですが...

しかし、この場合にreplace()メソッドがうまく機能しなかった理由はまだ推測しています...本当に奇妙です。

41
Axel M. Garcia

アクティビティの状態が既に保存されている場合、コミットを呼び出すのは安全ではありません。代わりにcommitAllowingStateLoss()を呼び出す必要があります。お役に立てれば!

編集:OKあなたの問題を詳しく調べましたが、問題は既に追加されているフラグメントを追加しようとしているということです。置換呼び出しまたは削除呼び出しを使用しても、これを行うことはできません。私が見つけた回避策は、フラグメントの新しいインスタンスを作成して毎回追加することです。フラグメントを削除または置換したら、GCへの参照ができるように、フラグメントへのすべての参照を削除するのが最善です。

12
schwiz

おそらくこの問題に直接関係していませんが、FragmentTransactionへの遷移を設定するとIllegalStateExceptionが発生し、遷移を設定しないと発生しないことにも気付きました。

この問題のバグは次のとおりです。 http://code.google.com/p/Android/issues/detail?id=25598

8
Johan Paul

Fragment.isAdded()メソッドを使用して、framentが既に追加されているかどうかを確認します。それに応じてフラグメントを置換または追加します。

1

私はこれを使用しました:

_if (getFragmentManager().findFragmentByTag(newFragment.getClass().getName()) != null) {
   transaction.remove(newFragment);
 }
_

フラグメントを追加しました

_MyFragment frag = new MyFragment(); 
transaction.add(R.id.container, frag, MyFragment.class.getName())
_

MyFragment.class.getName()tagを表します

1
Nartus Team

fragmentTransection.replace()の後にこれを試してください

fragmentTransection.addToBackStack(null);
fragmentTransection.commitAllowingStateLoss();
1
Saleh Sheper

if(mFragment.isAdded()){return; //または、呼び出し元に基づいてfalse/trueを返します}

0
Bombey77

このコードは私のためにうまく機能しています。これを試して

((MiActivity)getActivity()).addAccount = new AddAccount();
((MiActivity)getActivity()).addAccount.setArguments(params);
fragmentManager = getActivity().getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container((MiActivity)getActivity()).addAccount);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
0

setOffscreenPageLimitからViewpagerを削除すると、問題が解決しました。ありがとう。

フラグメントをループしてisAdded()がtrueであるかどうかを確認し、そのフラグメントを削除することで解決しました。 詳細はこちら

0
kylarsturn

FragmentTransaction.remove()からonTabUnselected()を呼び出してみましたが、このバグを回避できました。

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    ft.add(R.id.fragment_container, fragment, null);
}

@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    ft.remove(fragment);
}
0
ObviousChild