Skip to content

Snappy1

  • Home
  • Android
  • What
  • How
  • Is
  • Can
  • Does
  • Do
  • Why
  • Are
  • Who
  • Toggle search form

[FIXED] android – HiltViewModel is not cleared after navigation

Posted on November 11, 2022 By

Solution 1 :

Your understanding is incorrect, when you go from First to Second the First viewmodel remains alive because the First destination is in the backstack.

When you navigate from Second to First the Second destination is popped from the stack and the Second viewmodel will be destroyed.

This all works as described in the docs.

Problem :

After creating a new project in Android Studio and adding the relevant dependencies:

buildscript {
    ext {
        compose_version = '1.1.0-beta01'
    }
    dependencies {
        classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
    }

}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    id 'com.android.application' version '7.2.1' apply false
    id 'com.android.library' version '7.2.1' apply false
    id 'org.jetbrains.kotlin.android' version '1.5.31' apply false
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

------------

plugins {
    id 'com.android.application'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
    id "dagger.hilt.android.plugin"
}

android {
    compileSdk 32

    defaultConfig {
        applicationId "com.ohmenu.mytestapp"
        minSdk 25
        targetSdk 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables {
            useSupportLibrary true
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerExtensionVersion compose_version
    }
    packagingOptions {
        resources {
            excludes += '/META-INF/{AL2.0,LGPL2.1}'
        }
    }
}

dependencies {

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation "androidx.compose.ui:ui:$compose_version"
    implementation 'androidx.compose.material3:material3:1.0.0-alpha01'
    implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
    implementation 'androidx.activity:activity-compose:1.3.1'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
    debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
    debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"

    implementation("androidx.navigation:navigation-compose:2.5.0")


    implementation("com.google.dagger:hilt-android:2.38.1")
    kapt("com.google.dagger:hilt-android-compiler:2.38.1")
    implementation("androidx.hilt:hilt-navigation-compose:1.0.0")

}

// Allow references to generated code
kapt {
    correctErrorTypes = true
}

I use Hilt to manage dependency injections:

@HiltAndroidApp
class MyApp: Application() {}

interface IRepoAuth {
  val authStatus: String
}

class RepoAuth @Inject constructor(): IRepoAuth {
  override val authStatus = ""
}

@Module
@InstallIn(SingletonComponent::class)
object AppModule {

  @Singleton
  @Provides
  fun provideRepoAuth(): IRepoAuth { return RepoAuth() }
}

Then in my MainActivity, I use composition and navigation:

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MyTestAppTheme {
        MyNavGraph()
      }
    }
  }
}
@Composable
fun MyNavGraph(
  navController   : NavHostController = rememberNavController(),
  startDestination: String            = "FIRST"
) {
  NavHost(navController, startDestination) {
    composable("FIRST") {
      val firstVM: FirstVM = hiltViewModel()
      FirstScreen(navController = navController)
    }
    composable("SECOND") {
      SecondScreen(navController = navController)
    }
  }
}

@Composable
fun FirstScreen(
  navController: NavController,
  vm: FirstVM = hiltViewModel()
) {

  Column(modifier = Modifier.fillMaxSize()) {
    Text(text = "FIRST")
    Button(onClick = { navController.navigate("SECOND") }) {
      Text(text = "to SECOND")
    }
  }
}
@Composable
fun SecondScreen(
  navController: NavController,
  vm: SecondVM = hiltViewModel()
) {

  Column(modifier = Modifier.fillMaxSize()) {
    Text(text = "SECOND")
    Button(onClick = { navController.navigate("FIRST") }) {
      Text(text = "to FIRST")
    }
  }
}
@HiltViewModel
class FirstVM @Inject constructor(
  private val repoAuth: IRepoAuth
): ViewModel() {

  val status = repoAuth.authStatus

  init {
    println("AAA - FIRST VM INIT :")
  }

  override fun onCleared() {
    println("AAA - FIRST VM CLEAR :")
    super.onCleared()
  }
}
@HiltViewModel
class SecondVM @Inject constructor(
  private val repoAuth: IRepoAuth
): ViewModel() {

  val status = repoAuth.authStatus

  init {
    println("AAA - SECOND VM INIT :")
  }

  override fun onCleared() {
    println("AAA - SECOND VM CLEAR :")
    super.onCleared()
  }
}

The issue I have is when navigating between FirstScreen and SecondScreen, the logcat shows that the init logs are printed but not the onCleared logs.

READ  [FIXED] android - How to find the sdk.dir location on command-line environment?
Powered by Inline Related Posts

According to the documentation here : https://developer.android.com/jetpack/compose/libraries

“if [Screen] is a destination in a navigation graph, call hiltViewModel() to get an instance of [ViewModel] scoped to the destination“.

My understanding is that if a viewModel is scoped to a destination, whenever the navcontroller navigates to another destination, the current destination’s viewModel should be destroyed ?

Am I understanding incorrectly or am I doing something wrong in the implementation ?

Android Tags:android, android-jetpack-compose, android-jetpack-navigation, dagger-hilt

Post navigation

Previous Post: [FIXED] React-native android build fails due to missing files in the gradle cache?
Next Post: Can I use Google storage instead of iCloud?

Related Posts

[FIXED] android – Nativescript appium testing installs old version Android
[FIXED] google play – In-App Update install always failed with error code -100 in Android Android
[FIXED] android – Request in Retrofit returns inappropriate data Android
[FIXED] android – Flutter Local Notification Error : ‘int java.lang.Integer.intValue()’ on a null object reference Android
[FIXED] Error caused by: Could not find com.android.tools.build:gradle:4.0.0 Android
[FIXED] android – gradle says it fails to build because it couldnt find all files? Android

Archives

  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuándo
  • ¿Cuántas
  • ¿Cuánto
  • ¿Qué
  • Android
  • Are
  • At
  • C'est
  • Can
  • Comment
  • Did
  • Do
  • Does
  • Est-ce
  • Est-il
  • For
  • Has
  • Hat
  • How
  • In
  • Is
  • Ist
  • Kann
  • Où
  • Pourquoi
  • Quand
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welchen
  • Welcher
  • Welches
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Who's
  • Why
  • Wie
  • Will
  • Wird
  • Wo
  • Woher
  • you can create a selvedge edge: You can make the edges of garter stitch more smooth by slipping the first stitch of every row.2022-02-04
  • you really only need to know two patterns: garter stitch

Recent Posts

  • Can Vicks humidifier be used without filter?
  • What color is Spanish green?
  • How old is Jamie in The War That Saved My Life?
  • When should I use scalp massager for hair growth?
  • Can I put polyurethane over liming wax?

Recent Comments

No comments to show.

Copyright © 2023 Snappy1.

Powered by PressBook Grid Dark theme