后台的Android片段事务
我正在开发一个带有片段的应用程序。它有一个JavaScript接口,在主活动中调用该接口,并具有片段替换逻辑。当应用程序位于前台时,一切正常,但当应用程序位于后台时,片段事务替换不起作用。当我返回到我的应用程序时,我仍然看到旧的片段,而没有看到新的片段后台的Android片段事务,android,android-fragments,Android,Android Fragments,我正在开发一个带有片段的应用程序。它有一个JavaScript接口,在主活动中调用该接口,并具有片段替换逻辑。当应用程序位于前台时,一切正常,但当应用程序位于后台时,片段事务替换不起作用。当我返回到我的应用程序时,我仍然看到旧的片段,而没有看到新的片段 @JavascriptInterface public void beginCall(String toast) { FragmentTransaction fTrans; taskFragment = TaskFragment.
@JavascriptInterface
public void beginCall(String toast) {
FragmentTransaction fTrans;
taskFragment = TaskFragment.newInstance(toast,"");
fTrans = getSupportFragmentManager().beginTransaction();
fTrans.replace(R.id.frgmCont, taskFragment);
fTrans.commit();
}
怎么了?为什么片段事务在后台不工作?过了一段时间,我找到了答案:在onStop之后不可能执行片段事务,它将导致java.lang.IllegalStateException:在onSaveInstanceState之后无法执行此操作。我没有得到那个异常,因为JavascriptInterface是在一个单独的线程中执行的。当我强制我的代码在主线程中运行时,我得到了那个错误。所以我需要实现一个不同的逻辑,也使用一些活动生命周期方法,或者切换到多个活动逻辑。希望我的回答能帮助任何人
FragRecordSongList FragRecordSongList = new FragRecordSongList();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.addToBackStack(FragRecordSongList.class.getName());
ft.replace(R.id.fragContainer, FragRecordSongList, FragRecordSongList.class.getName());
ft.commit();
试试看,这可能会帮助您当应用程序处于后台时,某些用例或架构可能需要触发片段事务 我们创建了以下扩展函数:
fun FragmentTransaction.commitWhenStarted(lifecycle: Lifecycle) {
lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
fun onStart() {
lifecycle.removeObserver(this)
commit()
}
})
}
使用它就像任何其他版本的commit、commitNow、commitAllowingStateLoss一样。
如果活动状态至少已启动,则将直接调用观察者并执行片段事务。如果事务是在childFragmentManager上执行的,则生命周期可以取自活动或片段
transaction.commitWhenStarted(lifecycle)
@lilienberg评论了一个伟大的片段事务解决方案。如果您使用的是导航组件,则可以使用如下内容:
fun NavController.resumedNavigation(lifecycle: Lifecycle, destination: Int) {
if(lifecycle.currentState.isAtleast(Lifecycle.State.RESUMED)){
//App is resumed, continue navigation.
navigate(destination)
} else {
//When app is resumed, remove observer and navigate to destination/
lifecycle.addObserver(object: LifecycleObserver {
@OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
fun onResume() {
lifecycle.removeObserver(this)
navigate(destination)
}
})
}
}
findNavController(R.id.my_nav_host_fragment).resumedNavigation(
lifecycle, R.id.my_navigation_action)
您可以从活动或片段中调用此函数,如下所示:
fun NavController.resumedNavigation(lifecycle: Lifecycle, destination: Int) {
if(lifecycle.currentState.isAtleast(Lifecycle.State.RESUMED)){
//App is resumed, continue navigation.
navigate(destination)
} else {
//When app is resumed, remove observer and navigate to destination/
lifecycle.addObserver(object: LifecycleObserver {
@OnLifecycleEvent(value = Lifecycle.Event.ON_RESUME)
fun onResume() {
lifecycle.removeObserver(this)
navigate(destination)
}
})
}
}
findNavController(R.id.my_nav_host_fragment).resumedNavigation(
lifecycle, R.id.my_navigation_action)
从您的Activty的onResume()中调用beginCall()方法。@Drv,如果我这样做,它将破坏应用程序逻辑。这是一个传奇!