web-dev-qa-db-ja.com

IllegalStateException:フラグメント<ThisFragment>は現在FragmentManagerにありません

アプリのクラッシュの原因を追跡するのに問題があります。 ListViewを表示するフラグメントがあり、検索フィールド用のSlidingMenuもあります。そして、検索すると、検索結果に基づいてListViewアイテムが再入力されます。これで、新しく入力された結果からListViewアイテムを開こうとすると、アプリがクラッシュします。

例外はここでトリガーされます:

_@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mContent", mContent); //Exception made here
}
_

これはサポートライブラリのせいですか?これを解決するにはどうすればよいですか?

編集:

スタックトレースは次のとおりです。

_02-05 12:51:53.941: E/AndroidRuntime(11638): FATAL EXCEPTION: main
02-05 12:51:53.941: E/AndroidRuntime(11638): Java.lang.IllegalStateException: Fragment MyFragment{436749b0} is not currently in the FragmentManager
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.support.v4.app.FragmentManagerImpl.putFragment(FragmentManager.Java:546)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.sample.Android.app.SearchListActivity.onSaveInstanceState(SearchListActivity.Java:118)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.Activity.performSaveInstanceState(Activity.Java:1137)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.Java:1215)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.ActivityThread.performStopActivityInner(ActivityThread.Java:2972)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.ActivityThread.handleStopActivity(ActivityThread.Java:3031)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.ActivityThread.access$900(ActivityThread.Java:138)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1234)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.os.Handler.dispatchMessage(Handler.Java:99)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.os.Looper.loop(Looper.Java:213)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Android.app.ActivityThread.main(ActivityThread.Java:4787)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Java.lang.reflect.Method.invokeNative(Native Method)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at Java.lang.reflect.Method.invoke(Method.Java:511)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:789)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:556)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at dalvik.system.NativeStart.main(Native Method)
_

編集2:これが私のアクティビティです:

_private Fragment mFragment;

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

            ..........

    params = new Bundle();
    params.putInt("id", id);

    // set the Above View Fragment
    if (savedInstanceState != null)
        mFragment = getSupportFragmentManager().getFragment(
                savedInstanceState, "mFragment");
    else {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        SampleListFragment fragment = new SampleListFragment();
        fragment.setArguments(params);
        fragmentTransaction.add(R.id.list_fragment, fragment);
        fragmentTransaction.commit();
    }

    if (mFragment == null) {
        mFragment = new SampleListFragment();
        mFragment.setArguments(params);
    }
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.list_fragment, mFragment).commit();

    // set the Behind View Fragment
    Fragment searchFragment = new SampleSearchFragment();
    searchFragment.setArguments(params);

    getSupportFragmentManager().beginTransaction()
            .replace(R.id.activity_search, searchFragment)
            .commit();
}


@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mFragment",
            mFragment);
}
_

そして、私のSampleListFragmentには、次のメソッドがあります。

_public static boolean isNetworkAvailable(Activity activity) {
    ConnectivityManager connectivity = (ConnectivityManager) activity
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity == null) {
        return false;
    } else {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
    }
    return false;
}
_

Asynctaskの内部:

_..........
@Override
protected void onPostExecute(String result) {
    super.onPostExecute(null);

    if (null != pDialog && pDialog.isShowing()) {
        pDialog.dismiss();
    }

    if (isNetworkAvailable(getActivity())) { //Triggered NPE
_

here から、getActivity()が親アクティビティにアタッチされているかどうかを、呼び出す前にどのように知ることができますか?

18
Compaq LE2202x

フラグメントをonSaveInstanceStateに保存する前に、フラグメントがフラグメントマネージャーに追加されているかどうかを確認してください

@Override 
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (mFragment.isAdded()){
        getSupportFragmentManager().putFragment(outState, "mFragment", mFragment); 
    }
} 
34
Felipe Conde

私の場合、2つのフラグメントがありました(PopularMoviesFragment&TopRatedMoviesFragement)、PopularMoviesFragment onCreate of the Activityに入力され、もう1つはBottomNavigationView

そのため、アプリを開いてBottomNavigationViewを最小化(または他のアプリに移動)すると、この例外が発生します

Java.lang.IllegalStateException:Fragment TopRatedMoviesFragement {79d8905}は現在FragmentManagerにありません

onCreate()の私のコードは

if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {

        fragmentManager.beginTransaction()
                .replace(R.id.containerw, fragment_1, FRAGMENT_1)
                .addToBackStack(null)
                .commit();
    }else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){   

        fragmentManager.beginTransaction()
                .replace(R.id.container, fragment_2, FRAGMENT_2)
                .addToBackStack(null)
                .commit();
    }

したがって、以下のコードに示すように、私が行ったことは、TopRatedMoviesFragementを追加し、それをPopularMoviesFragmentに置き換えただけです。

if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {

        fragmentManager.beginTransaction()
                .add(R.id.container, fragment_2, FRAGMENT_2)
                // Its been added to avoid Fragment is not currently in the FragmentManager
                .replace(R.id.container, fragment_1, FRAGMENT_1)
                .addToBackStack(null)
                .commit();
    }else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){  

        fragmentManager.beginTransaction()
                .replace(R.id.container, fragment_2, FRAGMENT_2)
                .addToBackStack(null)
                .commit();
    }

これもお役に立てば幸いです。 :)

1
Kavin Raju S

最近、私は同じ問題に直面しました。私の場合、アクティビティのonBackPressed()が呼び出されたときにmFragmentを設定するのを忘れていました。つまり、ユーザーがA-> B-> Cをナビゲートすると、mFragmentはそれに応じてA、次にB、最後にCに変化します。ただし、戻るを押すと、現在のフラグメントは逆にB、次にAに変化しますが、mFragmentはまだCです。したがって、onSaveInstanceState中に、アクティビティはFragmentManagerにないCを保存しようとします。

重要な点は、mFragmentを適切に変更せずに、現在の[表示された]フラグメントを変更(追加または削除)している可能性があるということです。

1
Esmailian

私も同じ問題に直面しています。フラグメントをbundleStateに入れようとしたとき

_@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mContent",   mContent); //Exception made here
}
_

FragmentManagerputFragment()メソッドの実装を確認しました。のような

_ @Override
 public void putFragment(Bundle bundle, String key, Fragment fragment) {
    if (fragment.mIndex < 0) {
         throwException(new IllegalStateException("Fragment " + fragment
                    + " is not currently in the FragmentManager"));
    }
    bundle.putInt(key, fragment.mIndex);
  }
_

ここで、mIndexは、アクティブなフラグメント配列へのフラグメントインデックスです。したがって、_mIndex < 0_の場合、フラグメントは現在アクティブではないことを意味します。したがって、@ FelipeCondeが提案したように、mFragment.isAdded()をチェックすることが最善の解決策になる可能性があります。

1
Amol Desai

私の場合、フラグメントは、複数のタブを持ち、タブごとに1つのフラグメントを持つために、FragmentPagerAdapterを介してViewPagerに追加されます。

    List<Android.Support.V4.App.Fragment> lsFragments = new List<Android.Support.V4.App.Fragment>();
    lsFragments.Add(m_FragmentListDocument);
    lsFragments.Add(m_FragmentListNote);
    lsFragments.Add(m_FragmentListRenvoi);

    m_viewPager.Adapter = new TabsFragmentPagerAdapter(SupportFragmentManager, lsFragments, lsTitles);

OnSaveInstanceStateで、すべてのタブを保存したかったのですが、1つのタブが例外をスローしていましたJava.Lang.IllegalStateException: Fragment is not currently in the FragmentManager

protected override void OnSaveInstanceState(Bundle outState)
{
    base.OnSaveInstanceState(outState);

    SupportFragmentManager.PutFragment(outState, "FragmentListDocument", m_FragmentListDocument);
    SupportFragmentManager.PutFragment(outState, "FragmentListNote", m_FragmentListNote);
    SupportFragmentManager.PutFragment(outState, "FragmentListRenvoi", m_FragmentListRenvoi);
}

これは、ViewPagerによるものです。ViewPagerは、画面に表示されている現在のフラグメントと、(デフォルトでは)左側と右側のフラグメントをロードします。

その場合、ViewPagerを変更して、起動時にすべてのフラグメントをロードするのに十分な高さのOffscreenPageLimitを設定しました。次に、フラグメントがSupportFragmentManagerに追加され、OnSaveInstanceStateで例外がスローされませんでした。

m_viewPager.OffscreenPageLimit = 4;

それが役立つことを願っています...

0
Maxime Esprit