I'm testing this new library out and want to navigate to a login fragment if the user isn't signed in. This check is done in in a base fragment like:
abstract class SignedInFragment : Fragment() {
override fun onResume() {
super.onResume()
if (FirebaseAuth.getInstance().currentUser == null) {
NavHostFragment.findNavController(this /* Fragment */)
.navigate(R.id.action_login)
}
}
}
But this just ends up in a RuntimeException saying FragmentManager is already executing transactions:
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)
The navigation graph looks as following:
<?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" />
Should this kind of navigation be done in some other way? Am I missing something?
If you want to go back from Activity to Fragment. This is very simple just override onBackPressed() in your activity and call onBackPressed where you want.
In the Project window, right-click on the res directory and select New > Android Resource File. The New Resource File dialog appears. Type a name in the File name field, such as "nav_graph". Select Navigation from the Resource type drop-down list, and then click OK.
Looks like a bug in Android Architecture Components. I created a bug report regarding this issue here. I've found that temporary workaround for it is to delay the call to the navigation method so that the fragment manager can execute pending transactions.
val executor = Executors.newSingleThreadScheduledExecutor()
executor.schedule({
activity?.runOnUiThread { NavHostFragment.findNavController(this)
.navigate(R.id.action_login) }
}, 1, TimeUnit.MILLISECONDS)
or if you are using coroutines
launch(UI) {
delay(1L)
NavHostFragment.findNavController(this).navigate(R.id.action_login)
}
UPDATE:
This issue has been fixed in version 1.0.0-alpha02
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With