简体   繁体   中英

How to inject ViewModel into Activity using Hilt?

I have a ViewModel that I'm already injecting into a Composable. Now I want to inject the same instance of that ViewModel into my Activity. For example:

In AccountScreen.kt

@Composable
fun AccountScreen(accountViewModel: AccountViewModel = hiltViewModel()) {
    ...
}

and my Activity class:

class MainActivity : ComponentActivity() {
    @Inject
    lateinit var accountViewModel: AccountViewModel
}

should have the same instance of AccountViewModel.

I know using @Inject in the Activity as in the example above doesn't work. Hilt's documentation suggests using ViewModelProvider or by viewModels() instead, both of which give me a new instance of AccountViewModel, but I need the same instance as what's in the AccountScreen Composable.

I'm assuming AccountScreen is part of a NavGraph, since you mentioned you need same instance of the view model, you can consider specifying the ViewModelStoreOwner when you inject your ViewModel in your AccountScreen , so MainActivity and AccountScreen will share same instance of it.

@Composable
fun MyNavHost(
    ...
) {

    val viewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
        "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
    }

    NavHost(
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {

        composable(<Destination>) {  
           AccountScreen(accountViewModel: AccountViewModel = hiltViewModel(viewModelStoreOwner)) {
                  ...
           }
        }

        ...
    }
}

I ended up solving this by getting the parent Activity's ViewModel in my child Composable (AccountScreen in this case) like so:

val composeView = LocalView.current
val activityViewModel = composeView.findViewTreeViewModelStoreOwner()?.let {
    hiltViewModel<MyViewModel>(it)
}

Within my MainActivity I'm getting the ViewModel the standard way

private val accountViewModel: AccountViewModel by viewModels()

Thanks to @zgy for providing a helpful suggestion that led me to this solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM