后台的Android片段事务

后台的Android片段事务,android,android-fragments,Android,Android Fragments,我正在开发一个带有片段的应用程序。它有一个JavaScript接口,在主活动中调用该接口,并具有片段替换逻辑。当应用程序位于前台时,一切正常,但当应用程序位于后台时,片段事务替换不起作用。当我返回到我的应用程序时,我仍然看到旧的片段,而没有看到新的片段 @JavascriptInterface public void beginCall(String toast) { FragmentTransaction fTrans; taskFragment = TaskFragment.

我正在开发一个带有片段的应用程序。它有一个JavaScript接口,在主活动中调用该接口,并具有片段替换逻辑。当应用程序位于前台时,一切正常,但当应用程序位于后台时,片段事务替换不起作用。当我返回到我的应用程序时,我仍然看到旧的片段,而没有看到新的片段

@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,如果我这样做,它将破坏应用程序逻辑。这是一个传奇!