在getChildFragmentManager()之后调用getSupportFragmentManager()会导致IllegalStateException:递归进入executePendingTransactions

时间:2015-01-16 14:00:46

标签: android android-fragments google-maps-android-api-2 android-nested-fragment

我正在使用FrameLayout来显示片段

 <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@+id/bottom_layout"
        android:background="@android:color/white" >
    </FrameLayout>

并打开片段我正在使用此

ft.add(R.id.fragment_content, frag);
ft.commit();
fm.beginTransaction();

一个片段包含地图,所以我在布局文件中使用这些行

<fragment
        android:id="@+id/trafic_Alarm_main_mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.Utilities.MySupportMapFragment"
        android:layout_alignParentTop="true" />

这是我的Java代码

try{
mMap=(MySupportMapFragment)TabsActivity.fm.findFragmentById(R.id.trafic_Alarm_main_mapView)).getMap();
}catch (Exception e){
mMap=((MySupportMapFragment)getChildFragmentManager().findFragmentById(R.id.trafic_Alarm_main_mapView)).getMap();
}

现在,如果调用getChildFragmentManager()并切换到另一个使用getSupportFragmentManager开始事务的片段导致崩溃。提供日志

01-16 18:36:15.690    7294-7294/com.TrafikAlarm E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.TrafikAlarm, PID: 7294
    java.lang.IllegalStateException: Recursive entry to executePendingTransactions
            at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1461)
            at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:454)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

我正在使用android studio并编译这些库,

compile 'com.google.android.gms:play-services:6.5.87'
compile 'com.android.support:appcompat-v7:21.0.3'

当我使用eclipse时,我不需要使用getChildFragmentManager,一切都运行正常。

提前致谢。

5 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

由于您的上下文是片段,您是否尝试在使用它之前在您的子片段管理器上调用super?

超级(fragment.getChildFragmentManager());

答案 2 :(得分:1)

嗨,好像你有一个递归问题Recursive entry to executePendingTransactions,因为你不止一次地重新调用这个问题,并且在一个异常处理中,通过实践错误来捕获一个Exeption错误并尝试&#34;做某事()&#34;

try{

mMap=(MySupportMapFragment)TabsActivity.fm.findFragmentById(R.id.trafic_Alarm_main_mapView)).getMap();

}catch (Exception e){

mMap=((MySupportMapFragment)getChildFragmentManager().findFragmentById(R.id.trafic_Alarm_main_mapView)).getMap();

}

删除catch区域上的不必要的调用,如果出现新错误,请务必阅读日志cat,并在正确的{{1}中添加/删除片段使用@override的活动的@onCreate

希望它有所帮助。

答案 3 :(得分:0)

布局片段一次很棒,添加和忘记使用方式。除此之外您必须使用Java代码管理片段。

添加时,只需遵守一些规则,替换片段:

Int frameId = // id of host view
Fragment manager = // fragment manager, of Activity or a Fragment
String tag = // unique tag for the fragment
String clazz = // class name of the fragment
Bundle args = // initial data to be supplied to fragment instance

Fragment frg = manager.findFragmentbyTag(tag);

if(frg == null){
  frg = Fragment.instantiate(context,clazz,args);
}

if(!frg.isAdded()){
   manager.beginTransaction().add(frameId, frg, tag).commit();
}

如果片段还要在开始时显示嵌套片段,您可以在其onViewCreated()中使用上面的代码。

FragmentManager本质上是异步的,在commit()之后,它不会立即应用片段更改。提交计划在将来的某个时间发生。 executePendingTransactions()可用,但应谨慎使用。它使所有计划的事务立即运行,并且当它们运行时,您不能再次调用它。

答案 4 :(得分:0)

我找到了这个bug。我正在使用FragmentActivity管理器返回map对象,以删除导致问题而日志不是的地图片段。所以,我改变了

TabsActivity.fm.beginTransaction().remove((MySupportMapFragment) TabsActivity.fm.findFragmentById(R.id.trafic_Alarm_main_mapView)).commit();

TabsActivity.fm.beginTransaction().remove((MySupportMapFragment) getChildFragmentManager().findFragmentById(R.id.trafic_Alarm_main_mapView)).commit();