icerockdev / moko-mvvm

Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development
https://moko.icerock.dev/
Apache License 2.0
1.03k stars 95 forks source link

java.lang.IllegalStateException: Fragment ... not associated with a fragment manager. #109

Open alexluque opened 3 years ago

alexluque commented 3 years ago

We are using the latest version of Moko-MVVM at the time of this writing: 0.9.1. We have a Fragment which uses Jetpack's Navigation.

If we perform a screen rotation in Android and then we click on the button which performs the navigation the IllegalStateException occurs. It seems that the ViewModel is not properly reattached after rotation.

We've been checking and updating dependencies versions before submitting this ticket and we also replaced the Moko ViewModel by a pure Android ViewModel instance, in order to isolate the problem and to verify that the problem is actually related to this library.

Here's the stack trace:

java.lang.IllegalStateException: Fragment RegisterFragment{73ace6f} (b7f449b1-f9d9-4597-9777-5ba98a371014)} not associated with a fragment manager.
        at androidx.fragment.app.Fragment.getParentFragmentManager(Fragment.java:1038)
        at androidx.navigation.fragment.NavHostFragment.findNavController(NavHostFragment.java:109)
        at androidx.navigation.fragment.FragmentKt.findNavController(Fragment.kt:29)
        at com.farandsoft.ordersce.androidApp.views.register.RegisterFragment.navigateToLogin(RegisterFragment.kt:62)
        at com.farandsoft.ordersce.androidApp.views.register.RegisterFragment.access$navigateToLogin(RegisterFragment.kt)
        at com.farandsoft.ordersce.androidApp.views.register.RegisterFragment$observeViewModel$1.invoke(RegisterFragment.kt:44)
        at com.farandsoft.ordersce.androidApp.views.register.RegisterFragment$observeViewModel$1.invoke(RegisterFragment.kt)
        at dev.icerock.moko.mvvm.livedata.LiveData$addObserver$archObserver$1.onChanged(LiveData.kt:25)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at androidx.lifecycle.LiveData$1.run(LiveData.java:93)
        at android.os.Handler.handleCallback(Handler.java:754)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:163)
        at android.app.ActivityThread.main(ActivityThread.java:6388)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:930)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:820)

I'll be glad to provide any further information that you might need in order to check this problem out.

Alex009 commented 3 years ago

Hi! Can you show project code where I can debug this problem? Small reproducer will be good

alexluque commented 3 years ago

Hi Alex. Thank You so much for your rapid response.

Please, use this link from WeTransfer to download a Sample project which tries to reproduce as close as possible the configuration files that we have in our real project, as well as the navigation performed when the register button is clicked.

I've been setting up this project very quick. I hope you find everything you might need in order to reproduce the problem and to debug it accordingly. Excuse me for not providing you a valid test case. I had very little time to set up this project.

We are using Android Studio Preview Artic Fox Canary 2 for these projects.

Steps to reproduce the error:

  1. Install the app on a device.
  2. When in Register Screen, rotate the device to landscape and then rotate back to portrait.
  3. Click on the register button.
  4. The IllegalStateException will show up on the Debug console.

Thank you for your time.

Alex009 commented 3 years ago

did you use addObserver with lifecycle (from android architecture livedata) or without lifecycle? if you not pass lifecycle - you should control lifecycle by self and removeObserver when component life end.