Android FragmentManager已在执行事务。提交后初始化寻呼机何时安全?

Android FragmentManager已在执行事务。提交后初始化寻呼机何时安全?,android,android-fragments,Android,Android Fragments,我有一个托管两个片段的活动。活动在加载对象时开始显示加载程序。然后,加载的对象通过newInstance方法作为参数传递给这两个片段,并附加这些片段 final FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); trans.replace(R.id.container1, Fragment1.newInstance(loadedObject)); trans.replace(R.id.conta

我有一个托管两个片段的活动。活动在加载对象时开始显示加载程序。然后,加载的对象通过newInstance方法作为参数传递给这两个片段,并附加这些片段

final FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
trans.replace(R.id.container1, Fragment1.newInstance(loadedObject));
trans.replace(R.id.container2, Fragment2.newInstance(loadedObject));
trans.commit();
第二个片段包含一个android.support.v4.view.ViewPager和选项卡。在简历上,我们将其初始化如下

viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(adapter.getCount()); //the count is always < 4
tabLayout.setupWithViewPager(viewPager);
viewPager.setAdapter(适配器);
setOffscreenPageLimit(adapter.getCount())//计数总是小于4
tabLayout.setupWithViewPager(viewPager);
问题是android然后抛出

java.lang.IllegalStateException:碎片管理器已在执行 交易

使用此堆栈跟踪:(为了简洁起见,我从包名中取出了
android.support

v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1620) 在 app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:637) 在 v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143) 在v4.view.ViewPager.populate(ViewPager.java:1235) 在v4.view.ViewPager.populate(ViewPager.java:1083) 在 view.ViewPager.setOffscreenPageLimit(ViewPager.java:847)

数据显示如果
setOffscreenPageLimit(…)已删除。有没有其他方法可以避免这个问题


在生命周期中,碎片事务何时完成,以便我可以等待设置寻呼机?

如果您的目标是sdk 24及以上版本,则可以使用:

FragmentTransaction.commitNow()
而不是
commit()

如果您的目标是旧版本,请尝试呼叫:

FragmentManager.executePendingTransactions()

调用
commit()

后,只需在
片段中使用
childfragmentmanager()
查看页面

mPagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPagerAdapter);

我在快速替换2个片段并使用
executePendingTransactions()
时出现了这个异常。没有这样的称呼,也没有例外

我的案子是什么? 我打开一个片段a,在其
onResume()
(在某个条件下)中,我要求活动将该片段替换为片段B。此时出现异常

我的解决方案是使用
处理程序.post(runnable)
将查询放在线程队列的末尾,而不是立即运行它。通过这种方式,我们确保新事务将在任何以前的事务完成后执行

因此,我的解决方案非常简单:

Handler uiHandler = new Handler();
uiHandler.post(new Runnable()
{
    @Override
    public void run()
    {
        openFragmentB(position);
    }
});

如果有人使用Robolectric>3.6,并且至少通过4.0.2使用ViewPager,即使代码正确,您也可能会看到这一点

在跟踪机器人分子的问题时有相关的信息

在我写这个答案时,这个问题并没有得到解决,已知的唯一解决方法是使用@Config(sdk={27}),它似乎对某些人有效,但对我不起作用,或者在测试包中使用github上引用的相当长的代码实现ViewPagerShadow(如果更好的话,我可以把它包括在这里,但这可能不是一个足够相关的答案?)并使用@Config(shadows={ShadowViewPager.class})

我有一个类似的问题

添加碎片的维护活动

然后fragmentA回调mainactivity以fragmentB替换自身

MainActivity在使用fragmentB替换和提交事务时引发异常,fragmentmanager已在执行事务

这个问题实际上来自于碎片B

我在片段B中有一个TabHost,它需要
getfragmentmanager()
来添加tabfragment


用fragmentB中的
getfragmentmanager()
替换
getchildfragmentmanager()
解决问题。

我使用了
FragmentStatePagerAdapter
而不是
FragmentPagerAdapter
扩展了适配器,解决了我的问题

如果片段是动态的并且在运行时频繁更改,请使用
FragmentStatePagerAdapter

如果片段是静态的,并且在运行时不经常更改,请使用
FragmentPagerAdapter

受此启发,,

遇到了一个类似的错误,该错误与问题无关,但希望它能在使用firebase时帮助他人。 从
.addSnapshotListener()
中删除
活动
活动
,或该活动,并将其保留为空

 videosListener = videosCollectionRef
            .addSnapshotListener() { snapshot, exception ->

                if (exception != null) {
                    Log.e("Exception", "Could not retrieve documents: $exception")
                }

                if (snapshot != null) {
                    parseData(snapshot)
                }
            }
查看页面2 这是
ViewPager
时代的一个非常古老的答案,它帮助许多遇到这个问题的人解决了这个问题。以防你遇到
ViewPager2
并面临类似的问题

我们知道,当片段中有
ViewPager2
并且
FragmentStateAdapter
类有一个带有
fragment
参数的构造函数时,就会发生这种情况,所以您可以使用它来创建适配器

那么


我也有同样的问题。但是,我使用的是只获取
FragmentActivity
FragmentStateAdapter
构造函数:

package androidx.viewpager2.adapter;

public FragmentStateAdapter(
    @NonNull FragmentActivity fragmentActivity
) {
    this(fragmentActivity.getSupportFragmentManager(), fragmentActivity.getLifecycle());
}
即使它从
fragmentActivity
实例获取生命周期,它也根本不工作

然后,深入到
FragmentStateAdapter
的代码中,我看到了另一个构造函数,您可以在其中传递生命周期实例

package androidx.viewpager2.adapter;

public FragmentStateAdapter(
    @NonNull FragmentManager fragmentManager,
    @NonNull Lifecycle lifecycle
) {
    mFragmentManager = fragmentManager;
    mLifecycle = lifecycle;
    super.setHasStableIds(true);
}
因此,我更改了我的
PageAdapter
构造函数,将
FragmentManager
作为
childFragmentManager
接收,并从
viewLifecycleOwner
接收生命周期。并将这些参数传递给
FragmentStateAdapter
构造函数:

class MyPagerAdapter(
    fragmentManager: FragmentManager,
    lifecycle: Lifecycle
) : FragmentStateAdapter(fragmentManager, lifecycle) {
  //...
}
然后,当调用我的PagerAdap时
package androidx.viewpager2.adapter;

public FragmentStateAdapter(
    @NonNull FragmentManager fragmentManager,
    @NonNull Lifecycle lifecycle
) {
    mFragmentManager = fragmentManager;
    mLifecycle = lifecycle;
    super.setHasStableIds(true);
}
class MyPagerAdapter(
    fragmentManager: FragmentManager,
    lifecycle: Lifecycle
) : FragmentStateAdapter(fragmentManager, lifecycle) {
  //...
}
val myPagerAdapter = MyPagerAdapter(
    fragmentManager = childFragmentManager,
    lifecycle = viewLifecycleOwner.lifecycle
)