Backstack管理:仅在所有者的初始化阶段才必须创建重新启动器 [英] Backstack management : Restarter must be created only during owner's initialization stage

查看:1346
本文介绍了Backstack管理:仅在所有者的初始化阶段才必须创建重新启动器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MainActivity中使用底部导航栏来处理一些片段.这是用于在它们之间切换的代码:

I am using a bottom navigation bar in my MainActivity to handle some fragments. This is the code used for switching between them:

private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
    if (item.isChecked &&
        supportFragmentManager.findFragmentById(R.id.act_main_fragment_container) != null
    )
        return@OnNavigationItemSelectedListener false
    val fragment =
        when (item.itemId) {
            R.id.navigation_home      -> fragments[0]
            R.id.navigation_bookings  -> fragments[1]
            R.id.navigation_messages  -> fragments[2]
            R.id.navigation_dashboard -> fragments[3]
            R.id.navigation_profile   -> fragments[4]
            else                      -> fragments[0]
        }
    this replaceWithNoBackStack fragment
    return@OnNavigationItemSelectedListener true
}

replaceWithNoBackstack方法只是此方法的简写:

the method replaceWithNoBackstack is just a short-hand for this:

supportFragmentManager
    ?.beginTransaction()
    ?.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
    ?.replace(containerId, fragment)
    ?.commit()

问题是,当我在它们之间快速切换时,我的应用程序崩溃,但出现以下异常:

The problem is that when i switch faster between them, my app crashes with the following exception:

java.lang.IllegalStateException:仅在所有者的初始化阶段必须创建重新启动器 在androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:59) 在androidx.fragment.app.Fragment.performCreate(Fragment.java:2580) 在androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:837) 在androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1237) 在androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1302) 在androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) 在androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2075) 在androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1865) 在androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1820) 在androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1726) 在androidx.fragment.app.FragmentManagerImpl $ 2.run(FragmentManagerImpl.java:150) 在android.os.Handler.handleCallback(Handler.java:789) 在android.os.Handler.dispatchMessage(Handler.java:98) 在android.os.Looper.loop(Looper.java:164) 在android.app.ActivityThread.main(ActivityThread.java:6709) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769) 我已经搜索了很多,却找不到答案.

java.lang.IllegalStateException: Restarter must be created only during owner's initialization stage at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:59) at androidx.fragment.app.Fragment.performCreate(Fragment.java:2580) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:837) at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1237) at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1302) at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439) at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2075) at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1865) at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1820) at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1726) at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150) at android.os.Handler.handleCallback(Handler.java:789) at android.os.Handler.dispatchMessage(Handler.java:98) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6709) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769) I've been searching a lot and couldn't find an answer.

如果我执行API调用,将应用程序置于后台,等待响应,并且在我返回到应用程序时,由于我试图立即显示对话框片段而导致应用程序崩溃,我也会遇到此错误(我认为发生这种情况的原因是,在显示对话框片段时,从后台返回时重新创建片段的事务仍在进行中).我通过设置对话框的500ms延迟来解决此问题,因为我找不到其他解决方案.

I also got this error if I do an API call, put the app in background, wait for the response, and at the time I go back to the app, the app crashes because I am trying to display a dialog fragment immediately (the reason I think this is happening is that the transaction of recreating the fragment when coming back from the background is still in progress at the time of displaying the dialog fragment). I solved this in a hacky way by setting a 500ms delay for the dialog because I couldn't figure out other solutions.

请询问是否需要有关此的更多详细信息. 预先谢谢你!

Please ask if you need more details regarding this. Thank you in advance!

可能的温度解决方案

编辑 我通过将应用程序兼容性降低到androidx.appcompat:appcompat:1.0.2来解决了这个问题,但这只是一个临时解决方案,因为将来我必须对其进行更新.我希望有人能弄清楚.

EDIT I solved this issue by downgrading the app compat depedency to androidx.appcompat:appcompat:1.0.2 but this is just a temporary solution, since i will have to update it in future. I'm hoping someone will figure it out.

编辑2 我通过从片段事务中删除setTransition()解决了该问题.至少我知道android应用总体上没有良好过渡的原因

EDIT 2 I solved the issue by removing setTransition() from fragment transactions. At least I know the reason why android apps does not have good transitions in general

编辑3 也许最好的解决方案是使用ViewPager来处理底部栏导航,从而避免此问题并使工作顺利进行

EDIT 3 Maybe the best solution to avoid this issue and also make things work smoothly is just to use ViewPager to handle bottom bar navigation

推荐答案

如果您使用的是"androidx.core:core-ktx:1.0.2", 尝试更改为1.0.1

If you're using 'androidx.core:core-ktx:1.0.2', try changing to 1.0.1

如果您正在使用生命周期(或rxFragment)和androidx_appcompat:alpha05,请尝试更改versio.
例如:appcompat:1.1.0-beta01或1.0.2

If you're using lifecycle(or rxFragment) and androidx_appcompat:alpha05, try changeing versio.
ex) appcompat : 1.1.0-beta01 or 1.0.2

我认为在重用目标片段(onPause-onResume)时保存状态时,它会显示为错误.

I think's that it appears as an error when saving the state when the target fragment is reused (onPause-onResume).

这篇关于Backstack管理:仅在所有者的初始化阶段才必须创建重新启动器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆