导航架构组件 - onResume无法导航到片段

5
我正在测试这个新库并且想要在用户未登录的情况下导航到登录片段。这个检查是在一个基础片段中完成的,如下所示:
abstract class SignedInFragment : Fragment() {

override fun onResume() {
    super.onResume()
    if (FirebaseAuth.getInstance().currentUser == null) {
        NavHostFragment.findNavController(this /* Fragment */)
                .navigate(R.id.action_login)
    }
}

但这只会导致一个运行时异常,表示FragmentManager已经在执行事务:

    java.lang.RuntimeException: Unable to resume activity {me.hammarstrom.loco/me.hammarstrom.loco.MainActivity}: java.lang.IllegalStateException: FragmentManager is already executing transactions
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3645)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3685)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2898)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    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:767)

导航图如下所示:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@id/mainFragment">

<fragment
    android:id="@+id/loginFragment"
    android:name="me.hammarstrom.loco.ui.login.LoginFragment"
    android:label="LoginFragment" >
    <action
        android:id="@+id/action_loginFragment_to_signedInFragment"
        app:destination="@id/signedInFragment"  />
</fragment>
<fragment
    android:id="@+id/signedInFragment"
    android:name="me.hammarstrom.loco.ui.common.SignedInFragment"
    android:label="SignedInFragment" />
<fragment
    android:id="@+id/mainFragment"
    android:name="me.hammarstrom.loco.ui.main.MainFragment"
    android:label="MainFragment" />
<action
    android:id="@+id/action_login"
    app:destination="@id/loginFragment" />

这种导航方式是否有其他更好的实现方法?我有遗漏什么吗?
2个回答

7
看起来是Android Architecture Components中的一个bug。我已经在这个问题上创建了一个漏洞报告here。我发现临时解决方法是延迟呼叫导航方法,以便片段管理器可以执行待处理事务。
val executor = Executors.newSingleThreadScheduledExecutor()
executor.schedule({
        activity?.runOnUiThread { NavHostFragment.findNavController(this)
            .navigate(R.id.action_login) }
}, 1, TimeUnit.MILLISECONDS)

或者如果您正在使用协程

launch(UI) {
    delay(1L)
    NavHostFragment.findNavController(this).navigate(R.id.action_login)
}

更新:

此问题已在版本1.0.0-alpha02中修复。


1
此问题已在Navigation 1.0.0-alpha02中得到修复。根据发布说明

修复了在调用Fragment生命周期方法时导航时出现的IllegalStateException


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