Actual Combat of Android Architecture Components——ViewModel+LiveData

Among the Android architecture components officially provided by Google, there are ViewModel, LiveData, Lifecycle, DataBinding, etc., which together form a complete MVVM architecture, realize the separation of view and business logic, and provide friendly lifecycle management. This article will not involve the analysis of the principles of these components. If Baidu can find a bunch of them, I will not reinvent the wheel. I will directly teach you how to use the dry goods.

Before using these components, let's understand MVVM first:

1. MVVM

MVVM is Model (data) View (view) ViewModel (data view manager)

Concrete embodiment:

Model: bean (entity class), network request-related, database-related
View: layout, View, Activity, Fragment, etc. UI-related
ViewModel: similar to the Presenter in MVP, used to obtain information from the Model and pass it to the View for display. ViewModel and Views are bound together and interact with data through certain means (such as LiveData)

二、LiveData+ViewModel

LiveDatais an observable data holder class. It is lifecycle aware, which means it responds to the lifecycle of other application components such as Activities, Fragments, or Services. This ensures that LiveData only updates application component observers that are in an active lifecycle state.

Before using LiveData, you can first understand the official document Lifecycle , or check out my blog: "Android Architecture Components - Lifecycle"

ViewModel: An intermediate component for data interaction between the Model layer and the View layer. The architecture componentViewModelprovides a helper class for the UI controller, which is responsible for preparing data for the UI. ViewModelObjects are automatically persisted during configuration changes so that the data they hold is immediately available to the next Activity or Fragment instance.

View and ViewModel pass messages and data through LiveData. LiveData is an observable data holder, which allows application components to observe whether the data in LiveData has changed. LiveData will also follow the life cycle state of application components (Activity, Fragment, Service) to avoid memory leaks, so that your APP will not consume too much memory (LiveData has life cycle awareness. This means that unless Activity/fragment is Activation state (onStart but not yet onStop), otherwise the callback will not be initiated. When the fragment calls onStop, LiveData will automatically delete the observer)

LiveData is usually used together with ViewModel as follows:

1. Introduce

//lifecycle
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
//ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc02"

Non-androidx version: (Note that the compiled version is above 28, and the imported support library must also be above 28.0.0)

// Lifecycle
implementation "android.arch.lifecycle:extensions:1.1.0"
//ViewModel
implementation "android.arch.lifecycle:viewmodel:1.1.0"
//LiveData
implementation "android.arch.lifecycle:livedata:1.1.0"

LiveData is an abstract class, and its implementation subclasses include MutableLiveData, MediatorLiveData, and MutableLiveData is commonly used.

Use as follows:

Just inherit ViewModel (kotlin writing, please translate by yourself if you use java children's shoes)

/**
 * 基础的ViewModel,可以封装一些通用操作
 *
 */
abstract class BaseViewModel : ViewModel(){
}

LiveData:

class HomeViewModel : BaseViewModel() {
    //定义一个MutableLiveData,设置Value即可
    val data = MutableLiveData<String>()

    fun setData(name: String) {
           //这里可以去获取网络数据,操作数据库等
          //主线程可以使用setValue() ,异步线程使用postValue()
          data.value = name
    }
}

Listen for data changes in Fragment:

class HomeFragment : BaseFragment() {

    ...省略部分代码    

    private var homeViewModel: HomeViewModel? = null

    companion object {
        fun newInstance(): HomeFragment {
            return HomeFragment()
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        //获取ViewModel实例(如果我的ViewModele需要带参数怎么办?看文章后面)
        homeViewModel = ViewModelProviders.of(this)[HomeViewModel::class.java]

        //改变数据
        homeViewModel?.setData("测试")

        //监听ViewModel里面的data的数据变化
//        homeViewModel?.data?.observe(this,Observer<String>{data->{
//        } })
        homeViewModel?.data?.observe(this, Observer {
            mProgressDialog?.hide()
            Log.i("test", it)
        })

    }
}

In this way, the integration of LiveData and ViewModel is completed. We don’t need to pay attention to the life cycle. It is simple and clear. Please see the complete code: project source code

postscript

We just found out that getting the ViewModel instance in Fragment is done as follows:

 homeViewModel = ViewModelProviders.of(this)[HomeViewModel::class.java]

Here it will execute the no-argument constructor of HomeViewModel, so what about my ViewModel constructor with parameters?

The ViewModelProviders.of method provides a method, just pass in a ViewModelProviders.Factory object, the specific way of writing:

//构造函数带参数tips
class MyViewModel(private val tips:String?) :BaseViewModel() {

    val timeData = MutableLiveData<String>()

    init {
        val timer = Timer()

        timer.schedule(object : TimerTask() {
            override fun run() {
                val dataStr = TimeUtil.dateToSecondStr(Date())
                //异步线程使用postValue(),主线程用setValue()/postValue()
                timeData.postValue(tips+dataStr)
            }
        },0,1000)
    }
    
    //构造函数带参数,需要构建一个Factory,这样就可以用
    //ViewModelProviders.of(this, MyViewModel.Factory(tips)).get(MyViewModel::class.java)执行带参数的构造函数
    class Factory(private val tips:String?) : ViewModelProvider.Factory{
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            return MyViewModel(tips) as T
        }
    }
}

transfer:

myViewModel = ViewModelProviders.of(this, MyViewModel.Factory("当前时间:")).get(MyViewModel::class.java)
        

 

Guess you like

Origin blog.csdn.net/gs12software/article/details/103307967