Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
264 views
in Technique[技术] by (71.8m points)

android - How to use dependency injection for injecting constructor in a ViewModel

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...