What you need to know about ViewModel

Get into the habit of writing together! This is the 14th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

This article mainly explains the basic skills of using ViewModel

1. ViewModel constructor supports incoming Application

Customize a ViewModel inheritance AndroidViewModel:

class ApplicationViewModel(app: Application) : AndroidViewModel(app) {
    //获取Applicaction
    private val mApp: Application by lazy {
        getApplication()
    }
}
复制代码

We can getApplication()get the Application through the method.

2. The ViewModel constructor supports passing in other type parameters

ViewModel supports passing in a factory class to create a specific ViewModel type, so we directly inherit ViewModelProvider.Factorya custom factory class and pass in the custom factory class when creating a ViewModel.

For example, the following MainViewModelconstruction parameters we support pass in an Int type:

class CustomVMFactory(
    private val factory: ViewModelProvider.Factory,
    private val type: Int
) : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MainViewModel::class.java)) {
            return MainViewModel(type) as T
        }
        return factory.create(modelClass)
    }
}
复制代码

It can be found that our custom CustomVMFactoryfactory class also has to pass in an Activity 默认工厂to ensure that when our custom factory class cannot create a ViewModel, it will be handed over to the original Activity default factory for processing, which is equivalent to one 兜底作用, which essentially reflects An implementation of the static proxy pattern.

Use as follows:

private val mVM by viewModels<MainViewModel> {
    CustomVMFactory(
        defaultViewModelProviderFactory,
        5
    )
}
复制代码

3. Notes on using LiveData in ViewModel

Generally, we define LiveData in ViewModel like this:

//私有可变
private val data: MutableLiveData<Response<String>> = MutableLiveData()
//对外暴漏不可变
val data1: LiveData<Response<String>> get() = data
复制代码

We exposed immutability to the outside data1world by declaring an additional member variable and a member method:

image.png

Judging from the decompiled code, in fact, the additionally declared properties are not necessary at all, we only need getData1the method to obtain the immutable LiveData.

So we can change it like this:

//对外暴漏不可变
val data1: LiveData<String> get() =  MutableLiveData()
复制代码

Decompile to see the effect:

image.png

As you can see from the decompiled code, 暴露不可变的LiveData只额外声明了一个方法, reduces the declaration of an extra property.

4. Use of coroutines in ViewModel

Dependency implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"provides a coroutine extension property for ViewModel:viewModelScope

image.png

We can then use the viewModelScopeproperties directly to perform the 耗时操作sum 线程切换:

fun request() {
    viewModelScope.launch(Dispatchers.IO) {
        //执行耗时代码,比如网络请求
    }
}
复制代码

Guess you like

Origin juejin.im/post/7086607125949972487