FragmentStatePagerAdapter IllegalStateException:当前不在FragmentManager中

我在一些使用FragmentStatePagerAdapter的活动的onResume()中得到了这个。 使用设备的后退按钮时。 不总是。 不可重复。

我正在使用支持包v4,最新修订版(8)。

已经用谷歌搜索过,没有成功find有用的答案。

在源代码中,它被抛出:FragmentManager.java

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

但是为什么片段的索引<0呢?

实例化片段的代码:

 @Override public Fragment getItem(int position) { Fragment fragment = null; switch(position) { case 0: fragment = MyFragment.newInstance(param1); break; case 1: fragment = MyFragment2.newInstance(param2, param3); break; } return fragment; } @Override public int getCount() { return 2; } 

我也无法通过源调试,因为支持包不允许我附加源,出于某种原因……但这是一个不同的问题……

Solutions Collecting From Web of "FragmentStatePagerAdapter IllegalStateException:当前不在FragmentManager中"

如果您的ViewPager布局在片段(而不是激活)中:

mViewPager.setAdapter(new MyFragmentStatePagerAdapter(get Child FragmentManager()));

我在这里有同样的错误,但另一个原因。

在我的情况下,我在FragmentStatePagerAdapter中覆盖了getItemPosition。 我的意思是如果项目存在则返回位置,或者如果它不存在则返回POSITION_NONE。

好吧,我的问题是,当我的collections品变空时,我返回了POSITION_NONE。 这打破了一切。

我的修复是当我有一个空集合时返回POSITION_UNCHANGED。

希望它可以帮助别人。

理解这个bug的两个关键事项是:

  1. 有时会发生。
  2. 它发生在onResume()

鉴于此信息, ViewPager可能不会保留Fragment的状态。 如果你直接从Activity操作Fragment ,可能就是off-page Fragment被破坏而你的Activity试图操纵一个null片段。 要保留Fragment的状态,即使它不在当前屏幕中,修复也很简单:

 private static final int NUM_ITEMS = 2; ViewPager mPager = /** instantiate viewpager **/; mPager.setOffscreenPageLimit(NUM_ITEMS-1); 

你可以在这里读到它:

ViewPager片段随着时间推移会被破坏?

知道了,原因是,我每次都在onResume()中对适配器进行实例化。

如果我仅在活动的生命周期中实例化适配器一次,则不会再发生这种情况。

此exception意味着您尝试将片段附加到不再是正确状态的活动以附加片段。 这意味着,每当我们尝试附加片段( 特别是通过异步调用 )时,有人按下后退按钮的可能性很小,并且当您附加片段时,活动正在合并中被破坏。 这并不总是可重复的,因为它只是一种竞争条件,并且可能并不总是发生..

有两种方法可以解决这个问题:

1)当您调用活动的onSaveInstanceState并发布到您尝试附加片段时,会发生这种情况,因为android现在无法保存片段的状态,它会抛出exception。 要克服这一点,如果您没有保存片段的状态,请尝试使用

commitAllowingStateLoss() ,同时提交事务。

2)为了非常安全,在附加片段之前检查您的活动是否处于正确状态,请在onPause中使用以下代码:

  boolean isInCorrectState; public void onCreate{ super.onCreate(); isInCorrectState = true; } public void onPause() { super.onPause(); if(isFinishing()){ isInCorrectState = false; } } 

现在使用此标志在附加片段之前检查您的活动是否处于正确状态。含义附加片段iff isInCorrectState == true

对我来说,原因是别的。

在我的Loader.onLoaderReset()我清除了适配器中的数据。 当我离开应用程序时,onDestroy()导致加载程序重置,这清除了FragmentStatePagerAdapter 。 我认为它导致适配器清除对它的片段的所有引用,但不知何故, FragmentManager没有注意到并抛出exception。 对我来说似乎不合逻辑。

请注意,对我来说,它发生了Activity.onDestroy()

希望它可以帮到某人。

ViewPager中的片段是固定的,而不是尝试替换适配器中的片段,尝试提供一组不同的片段并更改notifyDataSet,或者利用FrameLayout在视图寻呼机选项卡的当前片段上显示另一个片段。

我的解决方案有效:

在Fragment级别应用的滑动手势以及ViewPager的默认滑动已禁用