Android FragmentManager已在执行事务。提交后初始化寻呼机何时安全?
我有一个托管两个片段的活动。活动在加载对象时开始显示加载程序。然后,加载的对象通过newInstance方法作为参数传递给这两个片段,并附加这些片段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
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
)