Reputation: 59
I am trying to implement the example on https://developer.android.com/jetpack/docs/guide. This explains how tan android app should be structured.
When I use the same code, I get following error.
java.lang.Class<com.example.UserProfileViewModel> has no zero argument constructor
I could figure out that this error has something to do with
viewModel = ViewModelProviders.of(this).get(UserProfileViewModel.class);
When I write a default zero input constructor for ViewModel I get the following error.
Attempt to invoke virtual method 'void android.arch.lifecycle.LiveData.observe(android.arch.lifecycle.LifecycleOwner, android.arch.lifecycle.Observer)' on a null object reference
I can not figure out the reason for this error and how to solve it.
Upvotes: 4
Views: 3738
Reputation: 779
If you want to provide viewmodel with constructor as a dependency in your Fragment, there is a different method for it,
Lets suppose you have a viewmodel class as belows,
class SampleViewmModel(dataManager:DataManager):ViewModel(){
//some logic
}
Then you will need to create a factory class to support above viewmodel like below,
class SampleFactory @Inject constructor(var dataManager:DataManager): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SampleViewModel::class.java)) {
return SampleViewModel(dataManager) as T
}
throw IllegalStateException()
}
}
Now in your module class, you can inject above classes as below, (Note-Datamanager class is injectible)
//Provide Factory
@Provides
fun provideFactory(dataManager:DataManager): SampleFactory {
return SampleFactory(dataManager)
}
//Provide actual viewmodel
@Provides
fun provideViewModel(sampleFactory: SampleFactory): SampleViewModel {
return ViewModelProviders.of(fragment, sampleFactory)[SampleViewModel::class]
}
No in your Fragment, you can inject your viewmodel just like any other dependency,
@Injetct
lateinit viewModel:SampleViewModel
Upvotes: 1
Reputation: 7104
You can use Koin as an alternative for Dagger. Koin have full support of Android Architecture ViewModel. It's extremely easy to use. I prefer it for small and mid-sized project.
// declared ViewModel using the viewModel keyword
val myModule : Module = module {
viewModel { MyViewModel(get()) }
...
}
// Just get it
class MyActivity() : AppCompatActivity() {
// lazy inject MyViewModel
val myViewModel : MyViewModel by viewModel()
}
Upvotes: 0