Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/187.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android FragmentStatePagerAdapter非法状态例外:<;MyFragment>;当前不在FragmentManager中_Android_Fragment - Fatal编程技术网

Android FragmentStatePagerAdapter非法状态例外:<;MyFragment>;当前不在FragmentManager中

Android FragmentStatePagerAdapter非法状态例外:<;MyFragment>;当前不在FragmentManager中,android,fragment,Android,Fragment,我在onResume()中的一些案例中得到了这个信息,这是一个使用FragmentStatePagerAdapter的活动。当使用设备的后退按钮时。不总是这样。不可复制 我正在使用支持包v4,最新版本(8) 已经用谷歌搜索过了,没有找到有用的答案 查看源代码,它被抛出到这里:FragmentManager.java @Override public void putFragment(Bundle bundle, String key, Fragment fragment) { if (f

我在onResume()中的一些案例中得到了这个信息,这是一个使用FragmentStatePagerAdapter的活动。当使用设备的后退按钮时。不总是这样。不可复制

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

已经用谷歌搜索过了,没有找到有用的答案

查看源代码,它被抛出到这里: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);
}

要理解这个bug,有两个关键点:

  • 有时也会发生
  • 它发生在
    onResume()
    根据这些信息,
    ViewPager
    可能没有保留
    片段的状态。如果您直接从
    活动
    操纵
    片段
    ,则可能是页面外的
    片段
    被销毁,而您的
    活动
    正试图操纵
    片段。要保留
    片段的状态,即使它不在当前屏幕中,修复非常简单:

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

    您可以在此处阅读:


    明白了,原因是我每次都在onResume()中提示适配器


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

    对我来说,原因是其他原因

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

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


    希望它对某人有所帮助。

    此异常表示您试图将片段附加到活动,但该活动的附加状态不再正确。这意味着,每当我们尝试附加片段时(,尤其是通过异步调用,),很可能有人按下了后退按钮,并且在附加片段时活动处于被破坏的状态。这并不总是可复制的,因为它只是一种竞争条件,可能并不总是发生

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

    1) 当您的活动的onSaveInstanceState被调用并发布到您试图附加片段的位置时,就会发生这种情况,因为android现在无法保存片段的状态,它将抛出异常。为了克服这个问题,如果您不保存片段的状态,请尝试使用

    提交事务时提交LowingStateLoss()

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

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

    现在,在附加片段之前,使用此标志检查活动是否处于正确状态。。意思是附加片段iffisInCorrectState==true

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

    我的解决方案是:


    我在这里也犯了同样的错误,但还有另一个原因

    在我的例子中,我在FragmentStatePagerAdapter中覆盖了getItemPosition。我的想法是返回位置,如果项目存在,或者返回位置,如果它不再存在

    嗯,我的问题是,当我的收藏变空时,我返回了位置“无”。这打破了一切

    我的解决办法是当我有一个空集合时,返回位置_不变


    希望它能帮助其他人。

    如果您的ViewPager被放置在片段中(而不是活动):


    setAdapter(新的MyFragmentStatePagerAdapter(getChildFragmentManager())

    我不理解抛出异常的逻辑,因为ViewPager没有保留片段的状态。。。如果片段被销毁,为什么ViewPager不只是重新创建它?不管怎么说,每次我加载活动时,我都会设置一个新的适配器来实例化片段,我不明白为什么它仍然试图访问其他片段…………所有这些片段都非常可怕,我已经有4个不同的异常,都与试图访问不再存在的东西有关“片段不再存在”、“未找到片段id 0xcf的视图”、“片段不再位于片段管理器中”(并且忘记了第四个片段).stacktraces甚至没有显示我的任何代码行,也没有关于这方面的有用指南或示例,只有一些非常简单的教程,它们总是有效的。但是一旦它变得更复杂一点…砰。嗯…是的,我记得被
    ViewPager
    片段的生命周期/管理弄糊涂了。它不是很好在开发者的网站上有文档记录,源代码相当密集,但是在研究了源代码之后有意义吗?对我来说,设计/API似乎有问题…但是如果你说只是缺少文档,我会花时间…有一天…研究源代码。我不能100%确定研究源代码是否有意义我会帮你的…我从来没有感觉到我已经获得了100%的工作解决方案,只是在等待我的应用程序随机中断,因为我所做的修复感觉不可靠…但也许我确实正确地实现了它,谁知道呢。我所知道的是,文档不是很清楚
    ViewPager
    是如何管理其容器片段的,所以可能be研究文档可以让你更深入地了解这一点……老实说,我不记得了。如果例外情况
        boolean isInCorrectState;
    
        public void onCreate{
        super.onCreate();
        isInCorrectState = true;
        }
    
        public void onPause() {
        super.onPause();
          if(isFinishing()){
            isInCorrectState = false;
           }
        }