This article will introduce the use of Google’s recommended architecture component ViewModel.
Why is there a ViewModel?
why? Seeing the name ViewModel is believed to be linked to the VM in the MVVM architecture.
But in my opinion, these two are not the same. If you want to implement an MVVM architecture app, following the previous three articles is enough.
And I speculate that Google may call it ViewModel for two reasons:
- The ViewModel architecture components serve the VM layer.
- It is easy to think of the MVVM architecture, which means that Google recommends that Android engineers use the MVVM architecture rather than a complicated MVP.
Of course these are digressions. Now that you can build MVVM applications without using ViewModel, what does ViewModel do?
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
Quick start
First we need to add the corresponding dependencies in app / build.gradle.
//ViewModel
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation "android.arch.lifecycle:viewmodel:1.1.1"
kapt "android.arch.lifecycle:compiler:1.1.1"
Then, let your VM layer inherit the ViewModel
class provided by the ViewModel component. If you need to use the Application
context, then inherit the AndroidViewModel
class.
class PaoViewModel constructor(private val repo: PaoRepo) :ViewModel(){
//...
}
In the PaoActivity
of the View layer, you need to modify it now.
class PaoActivity : AppCompatActivity() {
lateinit var mBinding : PaoActivityBinding
lateinit var mViewModel : PaoViewModel
lateinit var factory: ViewModelProvider.Factory
override fun onCreate(savedInstanceState: Bundle?) {
//....
mViewModel=ViewModelProviders.of(this,factory).get(PaoViewModel::class.java)
//...
}
}
Here are two concepts ViewModelProvider.Factory
and ViewModelProviders
. Before continuing, we need to understand how to build our own ViewModelProvider.Factory
.
ViewModelProvider.Factory
When you see this name, you naturally think of the factory pattern. Here we provide the mViewModel
instance we need. Of course, the ViewModel
is not so magical and will not help us automatically generate it, so we need to implement the ViewModelProvider.Factory
we need.
class PaoViewModelFactory : ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//return T
}
}
So how do you create a concrete instance? You can create new dependencies one by one here.
class PaoViewModelFactory constructor(): ViewModelProvider.Factory{
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
//////model
val remote=Retrofit.Builder()
.baseUrl(Constants.HOST_API)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PaoService::class.java)
val local=AppDatabase.getInstance(applicationContext).paoDao()
val repo = PaoRepo(remote, local)
/////ViewModel
mViewMode= PaoViewModel(repo)
if (modelClass.isInstance(mViewMode)){
return mViewMode as T
}else{
throw IllegalArgumentException("unknown model class $modelClass")
}
}
}
You’re done. Now that our ViewModel has the ability to rebuild the screen rotation activity, the data in the ViewModel is still valid.
End
The github address of this project:
More examples can be viewed:
The only regret is that we need to write too much templated code in order to provide a ViewModel.
//////model
val remote=Retrofit.Builder()
.baseUrl(Constants.HOST_API)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PaoService::class.java)
val local=AppDatabase.getInstance(applicationContext).paoDao()
val repo = PaoRepo(remote, local)
/////ViewModel
mViewMode= PaoViewModel(repo)
It would be great if you could not write.
of course can.
So the content of the next article is to rely on the retrieval container—Koin, to achieve the rapid injection of ViewModel.