Backstack中的活动引发java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作-Android

时间:2018-06-24 09:02:20

标签: android android-fragments kotlin

我正在开发一个具有2个活动的android应用,第一个是MainActivity,第二个是UpdateActivity。在我的主要活动中,我有一些片段,而在这些片段中,我使用 childFragmentManager 使用下面给出的代码

嵌套了一层以上的片段
fun changeFragmentTransfer(int: Int,index : Int? = null){
    fragment = when(int) {
        0 -> DemoLocalFragment.newInstance(10, "")
        1 -> ConfigureLocalFragment.newInstance("","")
        2 -> LocalListingFragment.newInstance("","")
        else -> DetailLocalFragment.newInstance(index!!,"")
    }
    if (index == null)
        childFragmentManager
                .beginTransaction()
                .replace(R.id.baseLocalFrameLayout,fragment).commit()
    else {
        (activity as MainActivity).replaceFrameInMainActivity(fragment!!)
    }
}

如果我在执行此功能后打开UpdateActivity,一切都很好,但是如果我在执行到这一点之前从MainActivity启动UpdateActivity,则我的应用程序将崩溃。

我不明白为什么当MainActivity在后台时该代码首先运行。

我检查了与同一主题link1 link2 link3 link4相关的这些问题,但在这里他们建议使用 commitAllowingStateLoss()我无法负担 commit()的费用,因为我的片段取决于此保存的实例状态。还有另外一种解决方案,可以在其中保存已保存的实例状态。

我得到的错误如下。

  

进程:com.idea_implement_india.bloombench_and_kossine.iotcontrollerapp,PID:21132       java.lang.IllegalStateException:onSaveInstanceState之后无法执行此操作           在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)           在android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2079)           在android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)           在android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)           在com.idea_implement_india.bloombench_and_kossine.iotcontrollerapp.Fragments.BaseLocalFragment.changeFragmentTransfer(BaseLocalFragment.kt:94)           在com.idea_implement_india.bloombench_and_kossine.iotcontrollerapp.Fragments.BaseLocalFragment.changeFragmentTransfer $ default(BaseLocalFragment.kt:84)           在com.idea_implement_india.bloombench_and_kossine.iotcontrollerapp.Fragments.DemoLocalFragment $ subHandler $ 1.handleMessage(DemoLocalFragment.kt:141)           在android.os.Handler.dispatchMessage(Handler.java:107)           在android.os.Looper.loop(Looper.java:238)           在android.app.ActivityThread.main(ActivityThread.java:6016)           在java.lang.reflect.Method.invoke(本机方法)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:937)           在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:798)

在此错误行

  

com.idea_implement_india.bloombench_and_kossine.iotcontrollerapp.Fragments.BaseLocalFragment.changeFragmentTransfer(BaseLocalFragment.kt:94)

对应于代码中的这一行

    childFragmentManager
            .beginTransaction()
            .replace(R.id.baseLocalFrameLayout,fragment).commit()

如果有人知道该问题的任何替代解决方案,请告知。 先感谢您。

2 个答案:

答案 0 :(得分:0)

即使您的MainActivity在后台,该代码也可能执行,因为commit()函数以异步方式处理片段事务。您的片段会在以后的某个时间(不受时间限制)中添加。

解决此问题的一种方法是使用commitNow()而不是commit()。这样可以确保片段的同步添加,并且还将保留saveInstanceState。

答案 1 :(得分:0)

此特殊问题已在Android的P版本中解决。如果您的应用程序以操作系统版本P为目标,则不会出现此错误,因为onStop()之后将调用onSaveInstanceState方法。

文档说

  

如果调用,此方法将在onStop()之后用于应用​​程序   以Build.VERSION_CODES.P开头的定位平台。对于   针对较早平台版本的应用程序,此方法将   发生在onStop()之前,并且不能保证它是否   会在onPause()之前或之后发生