导航架构组件 - 无法从 onResume 导航到片段
Navigation Architecture Component - Unable to navigate to fragment from onResume
我正在测试这个新库,如果用户未登录,我想导航到登录片段。此检查是在基本片段中完成的,例如:
abstract class SignedInFragment : Fragment() {
override fun onResume() {
super.onResume()
if (FirebaseAuth.getInstance().currentUser == null) {
NavHostFragment.findNavController(this /* Fragment */)
.navigate(R.id.action_login)
}
}
}
但这只是以 RuntimeException 告终,说明 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" />
是否应该以其他方式完成这种导航?我错过了什么吗?
看起来像是 Android 架构组件中的错误。我创建了一个关于这个问题的错误报告 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
中修复。
此问题已在 Navigation 1.0.0-alpha02
中修复。基于 release notes:
Fixed an IllegalStateException when calling navigate from Fragment
lifecycle methods
我正在测试这个新库,如果用户未登录,我想导航到登录片段。此检查是在基本片段中完成的,例如:
abstract class SignedInFragment : Fragment() {
override fun onResume() {
super.onResume()
if (FirebaseAuth.getInstance().currentUser == null) {
NavHostFragment.findNavController(this /* Fragment */)
.navigate(R.id.action_login)
}
}
}
但这只是以 RuntimeException 告终,说明 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" />
是否应该以其他方式完成这种导航?我错过了什么吗?
看起来像是 Android 架构组件中的错误。我创建了一个关于这个问题的错误报告 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
中修复。
此问题已在 Navigation 1.0.0-alpha02
中修复。基于 release notes:
Fixed an IllegalStateException when calling navigate from Fragment lifecycle methods