Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/179.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
我怎样才能预防;java.lang.IllegalStateException:已添加片段";更换碎片时?_Java_Android_Android Fragments - Fatal编程技术网

我怎样才能预防;java.lang.IllegalStateException:已添加片段";更换碎片时?

我怎样才能预防;java.lang.IllegalStateException:已添加片段";更换碎片时?,java,android,android-fragments,Java,Android,Android Fragments,尽管我努力防止片段被多次添加,但仍然会遇到java.lang.IllegalStateException:Fragment ready added:VideoFragment 我有一个活动,其中VideoFragment仅在onCreate中实例化。在我试图显示视频片段的唯一地方,我首先检查是否已经添加了该片段 private VideoFragment videoFragment; public void onCreate(Bundle savedInstanceState) { .

尽管我努力防止片段被多次添加,但仍然会遇到
java.lang.IllegalStateException:Fragment ready added:VideoFragment

我有一个活动,其中VideoFragment仅在onCreate中实例化。在我试图显示视频片段的唯一地方,我首先检查是否已经添加了该片段

private VideoFragment videoFragment;

public void onCreate(Bundle savedInstanceState) {
    ...
    videoFragment = new VideoFragment();
    ...
}

private void showVideoFragment() {
    if (!videoFragment.isAdded()) {
        FragmentTransaction transaction = getFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, videoFragment, "video").commit();
    }
}
我无法一致地重现此问题以在调试器中进行检查,但我的运行时错误报告继续报告异常
java.lang.IllegalStateException:Fragment已添加:VideoFragment
,用于用户,堆栈跟踪由Android类组成

/FragmentManager.java:1133→ android.app.FragmentManagerImpl.addFragment
/BackStackRecord.java:648→ android.app.BackStackRecord.run
/FragmentManager.java:1453→ android.app.FragmentManagerImpl.execPendingActions
/FragmentManager.java:443→ android.app.FragmentManagerImpl$1.run
/Handler.java:733→ android.os.Handler.handleCallback
/Handler.java:95→ android.os.Handler.dispatchMessage
/Looper.java:146→ android.os.Looper.loop
/ActivityThread.java:5487→ android.app.ActivityThread.main
/Method.java:-2→ java.lang.reflect.Method.invokeNative
/Method.java:515→ java.lang.reflect.Method.invoke
/ZygoteInit.java:1283→ com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
/ZygoteInit.java:1099→ com.android.internal.os.ZygoteInit.main
/NativeStart.java:-2→ dalvik.system.NativeStart.main
added in
isAdded()
的定义是否与用于检查片段事务的定义不匹配

或者活动中的视频片段引用是否有不同的方式?这是保存状态时需要显式处理的问题吗

或者是否有可靠的替代方法来检查片段是否已经添加


更新

我已经想出了如何半可靠地产生这个问题

  • 启动应用程序
  • 离开应用程序,运行其他程序一段时间。在我的Galaxy Nexus上(这几天相当慢),使用Chrome阅读一些新闻文章似乎就足够了。返回主屏幕时,如果渲染需要几秒钟,那么应用程序可能会抛出片段异常
  • 重新启动应用程序并触发片段更改
  • 如果我杀死并简单地运行应用程序,一切看起来都很好。或者,如果我离开应用程序并立即返回,它工作正常。只有应用程序在后台保留一段时间(足够从内存中删除吗?),才会出现片段问题

    我还尝试了onCreate,但没有效果

    View v = findViewById(R.id.fragment_container);
    if(v != null){
        Log.d(TAG, "disabling save for fragment_container");
        v.setSaveEnabled(false);
        v.setSaveFromParentEnabled(false);
    }
    
    我还试着检查
    Fragment-prior=getFragmentManager()
    片段优先级2=getFragmentManager().findFragmentById(R.id.Fragment\u容器),但这些事务出现
    null

    事实上,我的问题看起来很相似 虽然时间看起来不像内存/缓存效果那么重要。我完全不清楚为什么这个问题被解决了


    我将尝试生成一个简单的应用程序来复制这个问题。我当前的一个使用webrtc,而logcat输出中完全充斥着webrtc消息

    我在这里看到了一些东西:

  • 当系统重新创建
    活动时,可能会出现问题。您只需更改设备方向即可完成此操作
  • isAdded()
    返回
    false
    ,因为已重新创建了
    活动
    ,因此此方法用于不知道以前添加内容的
    视频片段
    的新安装
  • showVideoFragment()
    实际上是将片段添加到
    活动中,而不是仅仅显示它。我建议您将该方法重命名为类似“addVideoFragment”的名称,并将其移动到
    onCreate()
    方法如果这样做,您就可以解决问题。
  • 如果确实要显示或隐藏片段,请使用
    FragmentTransaction
    中的方法,例如:

     FragmentManager fm = getFragmentManager();
     fm.beginTransaction()
          .setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
          .show(somefrag) // or hide
          .commit();
    
  • 提示:
    当您事先知道您的片段始终是
    视频片段时,您可以简单地使用:

    <fragment 
         android:name="com.example.VideoFragment"
         android:id="@+id/video_fragment"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
    

    用这个实例做你想要的任何东西

    我想我已经成功地修复了这个错误,通过尝试在一个更简单的例子中重现这个错误:

    我犯了一个错误,在对
    onCreate
    的连续调用中添加了一个片段的多个实例(而不是视频片段),这是由活动的重新创建引起的。此片段添加没有触发
    java.lang.IllegalStateException:fragment ready added
    ,因为显然,只有尝试多次添加同一片段实例,而不是同一片段的多个实例时,才会发生这种情况

    调用fragment
    replace
    方法后,将为新的VideoFragment生成
    java.lang.IllegalStateException:fragment ready added
    ,即使使用replace只添加一次VideoFragment

    通过确保只添加一次不同的片段,替换为VideoFragment将不再生成
    java.lang.IllegalStateException:fragment ready added:VideoFragment
    ,至少对于上文所述的复制步骤是如此。IllegalStateException似乎与添加/替换视频片段无关,而是与被替换片段的状态有关

    我对这项决议感到不满,原因有二:

  • 错误消息具有误导性。它说视频片段已经被添加,我已经解决了这个问题,确保不同的片段不会被添加多次,这不会产生异常

  • replace
    文档具有很大的误导性。根据我的阅读,在调用replace之前,片段容器的状态应该是什么并不重要;结束状态应该完全由从replace参数添加的片段确定。我认为这种差异在相关问题中最为明显,尽管该问题的回答者不同意

  • 替换添加到容器中的现有片段。这本质上与为所有当前添加的片段调用remove(Fragment)相同,这些片段是使用相同的containerWebID添加的,然后使用此处给出的相同参数添加(int、Fragment、String)


    您是否有可靠再现此错误的特定配方?换句话说,用户采取了哪些步骤导致崩溃?丢失
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_layout);
        VideoFragment fragment = (VideoFragment) getFragmentManager().findFragmentById(R.id.video_fragmen);
    }