Reputation: 9912
I am using Hilt. After updating to 1.0.0-alpha03
I got warnings that @ViewModelInject
is deprecated and I should use @HiltViewModel
. But when I change it I got an error:
java.lang.RuntimeException: Cannot create an instance of class com.example.LoginViewModel
...
Caused by: java.lang.NoSuchMethodException: com.example.LoginViewModel.<init> [class android.app.Application]
Previous my ViewModel looked like this:
class LoginViewModel @ViewModelInject constructor(
application: Application,
private val repository: RealtimeDatabaseRepository
) : AndroidViewModel(application)
Now it looks like this:
@HiltViewModel
class LoginViewModel @Inject constructor(
application: Application,
private val repository: RealtimeDatabaseRepository
) : AndroidViewModel(application)
Fragment where ViewModel is injected:
@AndroidEntryPoint
class LoginFragment : Fragment(R.layout.fragment_login)
{
private val viewModel: LoginViewModel by activityViewModels()
}
Injected class:
@Singleton
class RealtimeDatabaseRepository @Inject constructor() { }
When I deleted private val repository: RealtimeDatabaseRepository
from ViewModel constructor it is working
I was using hilt version 2.30.1-alpha
when I updated to 2.31.2-alpha
, as USMAN osman suggested, the error is gone.
Upvotes: 12
Views: 18353
Reputation: 19844
My error was a dumb one which might help future people, adding a ViewModel to a feature module I forgot to add the kapt
and hilt
dependencies to the feature's build.gradle
file, meaning Hilt would never see the ViewModel.
Upvotes: 2
Reputation: 5581
I've seen this happens when the Fragment/Activity that is using the ViewModel is missing the @AndroidEntryPoint annotation, for instance:
import androidx.fragment.app.viewModels
@AndroidEntryPoint
class SampleFragment: BaseFragment() {
val viewModel: SampleFragmentViewModel by viewModels()
}
If the annotation is not present, the exact same error you describe will happen.
Upvotes: 13
Reputation: 1030
With new hilt version lots of stuff has been changed.
You also have to upgrade your hilt android, hilt compiler and hilt gradle plugin to:2.31-alpha
I made mock sample exactly the way you did i had same issue, after going through hilt's docs i found new way to inject dependencies to viewModels, you have to make separate module for dependencies which are going to inject in the viewModel
with special component called ViewModelComponent
:
@Module
@InstallIn(ViewModelComponent::class) // this is new
object RepositoryModule{
@Provides
@ViewModelScoped // this is new
fun providesRepo(): ReposiotryIMPL { // this is just fake repository
return ReposiotryIMPL()
}
}
here is what docs says about ViewModelComponent
and ViewModelScoped
All Hilt View Models are provided by the ViewModelComponent which follows the same lifecycle as a ViewModel, i.e. it survives configuration changes. To scope a dependency to a ViewModel use the @ViewModelScoped annotation.
A @ViewModelScoped type will make it so that a single instance of the scoped type is provided across all dependencies injected into the Hilt View Model.
link: https://dagger.dev/hilt/view-model.html
then your viewModel:
@HiltViewModel
class RepoViewModel @Inject constructor(
application: Application,
private val reposiotryIMPL: ReposiotryIMPL
) : AndroidViewModel(application) {}
UPDATE
It is not mandatory that you should be using ViewModelComponent
or ViewModelScoped
as i did in the above example. You can also use other scopes
or components
depends on your usecase.
Furthermore read docs, i put the dagger-hilt's link above.
Upvotes: 13