Search code examples
androidandroid-fragmentsandroid-viewmodeldagger-hilt

Dagger-Hilt @ViewModelInject sharedViewModel not injecting into fragment


I'm trying to make a shared injected view model between a fragment and an activity using the Jetpack tutorial.

The shared view model is successfully injected into the parent MyActivity but when the child is rendered, the application crashes due to dependency injection failure. I have provided the code below that created the issue.

Providing the Session Manager:

@InstallIn(ApplicationComponent::class)
@Module
class AppModule {
    @Provides
    @Singleton
    fun provideSessionManager(
        networkClient: NetworkClient
    ): SessionManager {
        return SessionManager(networkClient)
    }
}

To be injected into the Shared View Model:

class SharedViewModel @ViewModelInject constructor(
    private var sessionManager: SessionManager
) : ViewModel() {

    var name = MutableLiveData<String>("Shared View Model")
}

And is used by both a parent activity and child fragment.

class MyActionFragment() : Fragment() {
    private val viewModel: SharedViewModel by viewModels()
    override fun onActivityCreated(savedInstanceState: Bundle?) {
       super.onActivityCreated(savedInstanceState)
       Timber.d("View Model Name 1: ${viewModel.name.value}") // This line crashes
    }
}
class MyActivity : AuthenticatedBaseActivity() {
    private val viewModel: SharedViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Timber.d("View Model Name 2: ${viewModel.name.value}") // This line prints
    }
}

However, when the code is run, notice the activity created the ViewModel and accessed its values, but when the fragment tried to do the same, the application crashes:

**D/MyActivity: View Model Name 2: Shared View Model**
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.xxx.xxx, PID: 16630
    java.lang.RuntimeException: Cannot create an instance of class com.xxx.xxx.ui.main.SharedViewModel
        at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:54)
        at androidx.lifecycle.ViewModelLazy.getValue(ViewModelProvider.kt:41)
        at com.xxx.xxx.ui.main.MyActionFragment.getViewModel(Unknown Source:2)
        at com.xxx.xxx.ui.main.MyActionFragment.onActivityCreated(**MyActionFragment.kt:140**)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2718)

Additionally, when I remove the Hilt dependency injected sessionManager the fragment and view model are created without an issue.

Followed this post with no luck.

Any help on Hilt view model dependency injection with a shared model would be extremely appreciated!! Thanks!


Solution

  • You must provide all dependency , In your case NetworkClient not provided

    @Module
    @InstallIn(ApplicationComponent::class)
    object AppModule {
    
        @Singleton
        @Provides
        fun provideSessionManager(
            networkClient: NetworkClient
        ): SessionManager = SessionManager(networkClient)
    
        @Singleton
        @Provides
        fun provideNetworkClient() = NetworkClient()
    }
    

    In the Activity or Fragment use @AndroidEntryPoint

    @AndroidEntryPoint
    class MyActionFragment() : Fragment()
    
    
    
    @AndroidEntryPoint
    class MyActivity : AuthenticatedBaseActivity()