我正在开发一个具有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()
如果有人知道该问题的任何替代解决方案,请告知。 先感谢您。
答案 0 :(得分:0)
即使您的MainActivity在后台,该代码也可能执行,因为commit()函数以异步方式处理片段事务。您的片段会在以后的某个时间(不受时间限制)中添加。
解决此问题的一种方法是使用commitNow()而不是commit()。这样可以确保片段的同步添加,并且还将保留saveInstanceState。
答案 1 :(得分:0)
此特殊问题已在Android的P版本中解决。如果您的应用程序以操作系统版本P为目标,则不会出现此错误,因为onStop()之后将调用onSaveInstanceState方法。
文档说
如果调用,此方法将在onStop()之后用于应用程序 以Build.VERSION_CODES.P开头的定位平台。对于 针对较早平台版本的应用程序,此方法将 发生在onStop()之前,并且不能保证它是否 会在onPause()之前或之后发生