在后台执行Android Fragment事务

3

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

@JavascriptInterface
public void beginCall(String toast) {
    FragmentTransaction fTrans;
    taskFragment = TaskFragment.newInstance(toast,"");
    fTrans =    getSupportFragmentManager().beginTransaction();
    fTrans.replace(R.id.frgmCont, taskFragment);
    fTrans.commit();
}

出了什么问题?为什么片段事务在后台无法运行?


在您的Activity的onResume()方法中也调用beginCall()方法。 - Dhruvi
@Drv,如果我这样做的话,它会破坏应用程序的逻辑。 - inthy
4个回答

9

在一段时间后,我找到了答案:在onStop之后执行片段事务是不可能的,这会导致java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState异常。由于JavascriptInterface在单独的线程中执行,我没有遇到这个异常。当我强制我的代码在主线程中运行时,我得到了那个错误。因此,我需要实现一个不同的逻辑,同时使用一些Activity生命周期方法,或者切换到多个活动逻辑。希望我的答案对任何人都有帮助。


5

一些使用案例或架构可能需要在应用处于后台时触发片段事务。

我们创建了以下扩展函数:

fun FragmentTransaction.commitWhenStarted(lifecycle: Lifecycle) {
   lifecycle.addObserver(object : LifecycleObserver {
      @OnLifecycleEvent(value = Lifecycle.Event.ON_START)
      fun onStart() {
        lifecycle.removeObserver(this)
        commit()
      }
   })
}

可以像其他版本的commit、commitNow、commitAllowingStateLoss一样使用。如果activity状态已经至少为started,则观察者将直接被调用并执行fragment事务。如果事务在childFragmentManager上执行,生命周期可以从activity或fragment中获取。

transaction.commitWhenStarted(lifecycle)

1
 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();

尝试这个,可能会对你有所帮助。

1

@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)
              }
         })
     }
  }

您可以像这样从Activity或Fragment中调用此函数:
findNavController(R.id.my_nav_host_fragment).resumedNavigation(
                lifecycle, R.id.my_navigation_action)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接