Search code examples
androiddagger-hilt

Why can't I launch viewModel() two times when I use Hilt as DI in an Android Studio project?


I use Hilt as DI in an Android Studio project, and viewModel() will create an instance of SoundViewModel automatically.

Code A works well.

I think viewModel() will create an Singleton of SoundViewModel.

I think mViewMode_A will be assigned to mViewMode_B automatically without creating a new instance in Code B.

I think both mViewMode_A and mViewMode_B will point the same instance in Code B.

But I don't know why I get Result B when I run Code B, could you tell me?

Result B

java.lang.RuntimeException: Cannot create an instance of class info.dodata.soundmeter.presentation.viewmodel.SoundViewModel

Code A

@Composable
fun NavGraph( 
    mViewModel_A: SoundViewModel = viewModel()
) {
    ScreenHome(mViewMode_B = mViewMode1_A)      
}



@Composable
fun ScreenHome(
    mViewModel_B: SoundViewModel
 
) {
   ...  
}


@HiltViewModel
class SoundViewModel @Inject constructor(
    @ApplicationContext private val appContext: Context,
    ...
): ViewModel() {
   ...
  
}

Code B

@Composable
fun NavGraph( 
    mViewMode_A: SoundViewModel = viewModel()
) {
    ScreenHome()      
}



@Composable
fun ScreenHome(
    mViewMode_B: SoundViewModel = viewModel()  // I think  mViewMode_A will be assigned to mViewMode_B automatically without creating  a new instnace.
 
) {
   ...  
}

//The same

Solution

  • You need to pass the key in ViewModel initialization

    I'm not good at Composable but this will resolve your problem

    For creating a new instance of ViewModel we need to set Key property

    ViewModelProvider(requireActivity()).get(<UniqueKey>, SoundViewModel::class.java)
    

    key – The key to use to identify the ViewModel.

    val mViewMode_A = viewModel<SoundViewModel>(key = "NavGraph")
    val mViewMode_B = viewModel<SoundViewModel>(key = "ScreenHome")
    

    For Composable this link may help you separateViewmodel