MVVM架构:LiveData,ViewModel,kotlin,kotlin协程,DataBinding等

栏目: 编程工具 · 发布时间: 6年前

内容简介:先简单介绍一下上面几个下面介绍一下项目的架构,就以我们常用的Activity为入口开始介绍UI -> ViewModel -> Repository -> NetWork/Dao 箭头是单项的,也就是说,ViewModel持有Repository的引用,反过来没有,否则容易内存泄漏。 网络请求使用的是Retrofit,数据库Dao层这里省略了,最近太忙,等有时间再补充上去。Repository(仓库),负责提供数据,该数据可以从网络去取,也可以从数据库去取, ViewModel持有Repository的引用

先简单介绍一下上面几个

  • LiveData:见名知意,观察订阅模式,用于响应式编程,我们都知道RxJava的强大,但是LiveData相比于其,根本 不用管生命周期,应用会在页面"活着"的时候将数据同时到页面,当页面不可见或者销毁的时候,数据就中断响应,具体的使用参照项目代码
  • ViewModel 官方给出的介绍是,持有页面需要的数据,当手机旋转的时候,不会销毁数据。同时也是MVVM架构的VM层
  • kotlin/kotlin协程 kotlin毋庸置疑,做Android的几乎都在学习,kotlin1.3之后,协程已经成了稳定版本,我们可以放心使用。使用协程之后,我们几乎可以不用管线程, 它比线程要轻量,与LiveData配合使用,当网络响应了我们数据的时候,不需要使用Handler做线程切换,也不需要使用RxJava的操作符做切换了。我们之前的开发,习惯了 接口回调数据了,而kotlin协程,则可以使用同步的方式做异步的操作,代码简洁高效
  • DataBinding 谈到MVVM,很多人就离不开databinding,mvvm是一种思想,databing只是google给我们的一个工具,用来实现响应式编程,双向绑定的。

下面介绍一下项目的架构,就以我们常用的Activity为入口开始介绍

UI -> ViewModel -> Repository -> NetWork/Dao 箭头是单项的,也就是说,ViewModel持有Repository的引用,反过来没有,否则容易内存泄漏。 网络请求使用的是Retrofit,数据库Dao层这里省略了,最近太忙,等有时间再补充上去。Repository(仓库),负责提供数据,该数据可以从网络去取,也可以从数据库去取, ViewModel持有Repository的引用,也就是可以将仓库的数据拿来自己持有,然后将数据给到UI层。大致的流程就是这样。 下面我们说一下项目中的细节:

先思考一个问题?在项目中,我们使用协程,当页面销毁的时候,我们怎么取消请求? 这里我么使用ViewModel自带的viewModelScope.launch,他会在页面销毁的时候自动取消请求,不过必须要使用AndroidX,我们可以写一个BaseViewModel

open class BaseViewModel:ViewModel() {
    fun<T> launch(block: suspend () -> Unit, error: suspend (Throwable) -> Unit, liveData: StateLiveData<T>, isShowLoading:Boolean = true) = viewModelScope.launch {
        try {
            if(isShowLoading){
                liveData.postLoading()
            }
            block()
        } catch (e: Throwable) {
            liveData.postError()
            error(e)
        }finally {
            liveData.postSuccess()
        }
    }
}

class ArticleViewModel(private val respository: ArticleRepository) : BaseViewModel() {
    val data = StateLiveData<List<Data>>()

    fun getArticle() {
        launch({
            respository.getArticle()?.let {
                data.postValueAndSuccess(it)
            }
        }, {

        }, data)
    }
}

复制代码

StateLiveData是一个由状态的LiveData,这样我们可以在BaseViewModel的launch里面直接发送loading等用于界面交互

class StateLiveData<T> : MutableLiveData<T>() {

    enum class State {
        Idle, Loading, Success, Error
    }

    val state = MutableLiveData<State>()

    init {
        initState()
    }

    fun postValueAndSuccess(value: T) {
        super.postValue(value)
        postSuccess()
    }

    private fun initState() {
        state.postValue(State.Idle)
    }

    fun postLoading() {
        state.postValue(State.Loading)
    }

    fun postSuccess() {
        state.postValue(State.Success)
    }

    fun postError() {
        state.postValue(State.Error)
    }
}
复制代码

我们如何根据服务端的状态码来进行不同操作? 这里我们采用在Retrofit的Call对象上面扩展了一个await的函数的方式,以后自己的模块的NetWork直接继承BaseNetWork即可

open class BaseNetwork {

    suspend fun <T> Call<T>.await(): T {
        return suspendCoroutine {
            enqueue(object : Callback<T> {
                override fun onFailure(call: Call<T>, t: Throwable) {
                    it.resumeWithException(t)
                }

                override fun onResponse(call: Call<T>, response: Response<T>) {
                    if (response.isSuccessful) {
                        val body = response.body()
                        if (body != null) {
                            body as BaseRes<T>
                            if (body.errorCode == 0)
                                it.resume(body)
                            else if(body.errorCode == 100){
                                // 比方说登录超时等
                            }else{
                                it.resumeWithException(RuntimeException(body.errorMsg))
                            }
                        } else {
                            it.resumeWithException(RuntimeException("response body is null"))
                        }
                    } else {
                    }

                }
            })
        }
    }
}
复制代码

github: github.com/wfqdroid/mv…

参考: juejin.im/post/5ceddb… blog.csdn.net/guolin_blog… developer.android.com/topic/libra…


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ActionScript 3.0 Cookbook

ActionScript 3.0 Cookbook

Joey Lott、Darron Schall、Keith Peters / Adobe Dev Library / 2006-10-11 / GBP 28.50

Well before Ajax and Microsoft's Windows Presentation Foundation hit the scene, Macromedia offered the first method for building web pages with the responsiveness and functionality of desktop programs......一起来看看 《ActionScript 3.0 Cookbook》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试