AAC trial packaging

Keywords: Android network Google github

The full name of aac is Android architecture components. Google recently released an official version and was immediately attracted by it. Isn't that the magic medicine to improve the traditional MVP?
To add dependency, we will not repeat it. For many examples on the Internet, this article just encapsulates ViewModel and LiveData!

1. Create ViewModel

import android.arch.lifecycle.MediatorLiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel
import com.blk.resp.RespLiveData
import com.lzy.okgo.model.HttpParams

/**
 * Created by gcy on 2018/2/1 0001.
 */
class DemoViewModel<T> : ViewModel() {
    private val params = MutableLiveData<HttpParams>()

//    val resultLiveData = ReposLiveData().apply {//Pay attention to the ingenious design here
//        this.addSource(organizationLiveData) { it?.let { this.organization = it } }
//    }


    lateinit var resultLiveData: RespLiveData<T>

    val isLoadingLiveData = MediatorLiveData<Boolean>()/*.apply {
        this.addSource(resultLiveData) { this.value = false }
    }*/

    val throwableLiveData = MediatorLiveData<Throwable>()/*.apply {
        this.addSource(resultLiveData) { it?.second?.let { this.value = it } }
    }*/

    val reposLiveData = MediatorLiveData<T>()/*.apply {
        this.addSource(resultLiveData) { it?.first?.let { this.value = it } }
    }*/

    fun setParams(params: HttpParams, data: RespLiveData<T>) {
        resultLiveData = data
        resultLiveData.apply {
            this.addSource(this@DemoViewModel.params) { it?.let { 
            this.params = this@DemoViewModel.params.value } }
        }

        startInitProp()
        this@DemoViewModel.params.value = params
        isLoadingLiveData.value = true
    }

    private fun startInitProp() {
        isLoadingLiveData.apply {
            this.addSource(resultLiveData) { this.value = false }
        }
        throwableLiveData.apply {
            this.addSource(resultLiveData) { it?.second?.let { this.value = it } }
        }
        reposLiveData.apply {
            this.addSource(resultLiveData) { it?.first?.let { this.value = it } }
        }
    }

}

The above code refers to the example of a God in github, and the specific address cannot be found. In this code, ViewModel contains multiple LiveData, which are loading (to show progressbar and so on), loading success and failure.

2. Simple encapsulation of LiveData

import android.arch.lifecycle.MediatorLiveData
import com.lzy.okgo.model.HttpParams

/**
 * Created by gcy on 2018/2/1 0001.
 */
abstract class RespLiveData<T> : MediatorLiveData<Pair<T?, Throwable?>>() {
    abstract var params: HttpParams?
    abstract var url: String
}

The code is very simple. In practice, you can customize your own parameters according to your needs. This is just an example!
Let's say that the data of String type requested now can be used as a starting point

import com.blankj.ALog
import com.lzy.okgo.model.HttpParams
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers

/**
 * Created by gcy on 2018/2/1 0001.
 */
class RespStringLiveData : RespLiveData<String>() {
    private var disposable: Disposable? = null
    override var params: HttpParams? = null
        set(value) {
            field = value
            ALog.e("RespStringLiveData now req network")
            disposable = Observable.create<String> {
                Thread.sleep(5000)
                it.onNext("123")
                it.onComplete()
            }
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe({ this@RespStringLiveData.value = Pair(it, null) }, { this@RespStringLiveData.value = Pair(null, it) })

        }

    override var url = ""

    override fun onInactive() {
        super.onInactive()
        if (disposable?.isDisposed?.not() ?: false) {
            disposable?.dispose()
        }
    }

}

You can write the processing logic of disposable to the base class. Here I'm simply delaying 5 seconds to simulate network requests.
So far, the basic logic is finished!

3. Test

 fun testAAc(){
        var viewModel = DemoViewModel<String>()
        viewModel.setParams(HttpParams(),RespStringLiveData())
        viewModel.isLoadingLiveData.observe(this, Observer{ALog.e("aac Currently loading: $it")})
        viewModel.reposLiveData.observe(this, Observer { ALog.e("aac succeed: $it") })
        viewModel.throwableLiveData.observe(this, Observer { ALog.e("aac Failed: $it") })
    }

Take a look at the log output:

Basically perfect. If I have better suggestions, although I don't log in to the blog often, I can also leave a message to discuss and make progress together.

Posted by greepit on Sat, 25 Apr 2020 08:08:56 -0700