Home > Software design >  Why viewModel not cleared automatically?
Why viewModel not cleared automatically?

Time:06-18

I have a strange behavior in my application.

I have 1 navigation graph, and my problem is, when I navigate to Fragment A, the viewModel is created correctly, after that I navigate to Fragment B and then navigate back to Fragment A, although Fragment A onDestroy fun called, but the viewModel onCleared fun not, and every objects are the same inside viewModel.

Intesting, but If I navigate from Fragment A to Fragment A1 with an action, so not with the drawer menu, and go back, and after that I navigate again to A1, the A1 viewModel is cleared well. So it is possible that only the main manues affected?

In my another application when I navigate back to Fragmant A, onCleared() called, and it is the expected behavior for me, I don't know what is the problem with my new implementation.

I use Hilt to DI, and I also use a BaseViewModel class, but without it, it does the same problem.

[UPDATE] When I go back from Fragment B to Fragment A by selecting Fragment A menu item in navigation drawer and after that I go back to Fragment B by nav drawer, Fragment B viewModel doesn't cleared.

But If I first time use that back button to navigate back to the start destination which is Fragment A, and after that I navigate again to Fragment B, Fragment B viewModel is cleared is colled.

gradle:

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1'

    nav_version = "2.4.2"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

    /**
     * Hilt
     * */
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-compiler:$hilt_version"

VeiwModelInit:

    private val viewModel by viewModels<ErrorTicketBrowserViewModel>()

CodePudding user response:

The ViewModel remains in memory until the Lifecycle it's scoped to goes away permanently: in the case of an activity, when it finishes, while in the case of a fragment, when it's detached. so in your case Fragment A is not detached, Fragment A is still existing in the navigation stack and you are navigating back from B to A using pop back stack.

"Starting in Navigation 2.4.0-alpha01, the state of each menu item is saved and restored when you use setupWithNavController" also according to google documentation about navigation drawer, the navigation drawer will save the state of each item, that's why you navigate to back to B from the drawer the view model didn't get cleared.

To achieve view model recreation in this case, you can create a function in the view model which reset view model states, and call this function in the top of on onCreateView or onViewCreated in your fragment

  • Related