当前位置:   article > 正文

Android Mvvm设计模式的详解与实现_安卓开发mvvm

安卓开发mvvm

一、介绍

        在开发设计模式中,模式经历了多次迭代,从MVC到MVP,再到如今的MVVM。发现的过程其实很简单,就是为了项目更好的管理。

        设计模式严格来说属于软件工程的范畴,但是如今在各大面试中或者开发中,设计模式被问的很多。特别是八股文的二十三种设计模式,可分三大类:行为型、结构型、创建型。

二、模式介绍

        模式的设计更多的体现在管理与架构能力,即使在项目中,你不用任何设计模式,代码也可以正常的跑起来,但是通过模式设计以后,在项目管理与质量控制,以及解耦等场景特别方便。

        任何设计模式和手段都是为了项目的更好管理,这种模式更像一种流程。从技术角度来分析,不能作为衡量一个人的技术好坏,但是可以作为参考,来判断一个人的综合能力以及设计、架构能力。

了解设计模式,可以提高一个人的综合能力。

三、MVMM详解与设计

MVVM是什么

        目前在做有UI展示的一些项目或者端,都在说MVVM设计模式。MVVM全程view-viewModel-Model。还是分为三层,View层,viewModel:view与业务层,Model数据业务层

View:是我们fragment或者Activity界面,主要处理UI渲染和交互的

viewModel:介于view与Module之前,处理数据与逻辑上的,将Model请求的结果返回给view层

Model:与viewModel打交道,将view需要的数据通过Model层来请求,然后将请求到的结果返回给viewModel。

Mvvm流程

        在Mvvm设计模式中,view主要就是做数据与UI的绑定,常见的View与Model没有直接交互,需要申明都是通过ViewModel进行交互的。ViewModel从名字就可以看出,是View与Model的拼写,所以肯定是与View和Moel有关,在MVVM中,ViewModel的核心作用就是作为View与Model的桥梁,将View的需求告诉Model,然后从Model中将结果拿到,处理好给View,View进行渲染。

Mvvm的助手databinding:

        通过Google官方我们也了解到,MVVM的推波导致了DataBinding的被很好的推广,在Mvvm中,View中的绑定和页面的view是通过Databinding来完成,很多开发者可能还没体验过DataBinding,甚至也没有使用过,这个也不影响到Mvvm的使用,因为DataBinding只负责View与Data的绑定,即使你不会可以手动处理。

如果想了解DataBinding的小伙伴,可以看博主一下的文档:

Android databinding的接入使用与详解(一)_android databinding使用_蜗牛、Z的博客-CSDN博客

Android databinding之RecycleView使用与讲解(二)_android databinding recyclerview_蜗牛、Z的博客-CSDN博客

Android databinding之数据单向与双向绑定详解与使用(三)_databinding双向绑定_蜗牛、Z的博客-CSDN博客

Android databinding之BindingAdapter与BindingConversion详解与使用(四)_蜗牛、Z的博客-CSDN博客

Android databinding之BindingMethod与BindingMethods介绍与使用(五)_android开发bindingmethods的使用_蜗牛、Z的博客-CSDN博客

Android DataBinding之布局include 和 viewStub详解与使用(六)_databinding viewstub_蜗牛、Z的博客-CSDN博客

Android DataBinding之布局中(layout)事件、运算逻辑、资源、工具类的使用与详解(七)_databinding layout_蜗牛、Z的博客-CSDN博客

新手礼包:

        这几篇文档基本都是从零开始学databinding的文章,只要你跟着看,慢慢实践里面的dmeo,都是没问题的。以上新手礼包可以帮你很好的处理Mvvm中数据的绑定

数据传递MutableLiveData:

通过以上知道ViewModel与View进行数据交互,他们之间如何传递数据?在viewmodel中提供了

MutableLiveData,它继承了LiveData,类似事件订阅,你发送了数据,在view中订阅即可,数据将会回传到订阅处。LiveData也支持生命周期的绑定,防止数据订阅中,当前页面销毁,数据还在订阅,导致页面发生内存泄露。

四、实战

        通过以上的学习,我们大概了解了Mvvm包括哪些?如何架构和搭建MVVM。通过关键模块的处理我们将继续学习实战。

依赖库:
  1. implementation "androidx.lifecycle:lifecycle-viewmodel:2.0.0"
  2. implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"

Model模块

model主要是数据处理,在搭建代码的时候,我们最好有良好的编程风格,可以先搭建一个基础、抽象类,后面的model都继承直接使用,即使是空类也要写一个,方便以后扩展。

  1. open abstract class BaseModel {
  2. }
  1. //一般梳理数据类比较多
  2. class MyModel : BaseModel() {
  3. //网络数据的获取
  4. //数据库的操作
  5. //本地的数据缓存:添加与删除
  6. public fun getInitData():String{
  7. return "init data that info"
  8. }
  9. }

Model的是和数据打交道,处理好,我们就可以处理搭建ViewModel了

ViewModel层:

ViewModel层夹在View与model之间,是逻辑的中转,view要什么找ViewModel,model通过ViewModel把数据传递给View。

ViewModel这里面主要有两块:搭建和创建

搭建

搭建需要继承public AndroidViewModel(@NonNull Application application),由于ViewModel需要与View合作,所以还需要了解当前的对象生命周期防止内存泄露等发生。

这里需要使用到接口:LifecycleObserver

LifecycleObserver用法:

直接继承,然后通过状态绑定对应的方法,当lifecycle绑定完就可以分发生命周期状态

  1. @OnLifecycleEvent(Lifecycle.Event.ON_START)
  2. public fun onstart(){
  3. log("onstart")
  4. }
1、生命状态回调
  1. //定义了页面监听生命周期监听
  2. interface BaseViewModelLifecycleObserver : LifecycleObserver {
  3. companion object{
  4. const val TAG="life"
  5. }
  6. @OnLifecycleEvent(Lifecycle.Event.ON_START)
  7. public fun onstart(){
  8. log("onstart")
  9. }
  10. @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
  11. public fun onStop() {
  12. log("onStop")
  13. }
  14. @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
  15. public fun onResume() {
  16. log("onResume")
  17. }
  18. @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
  19. public fun onPause() {
  20. log("onPause")
  21. }
  22. @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
  23. public fun ondestory() {
  24. log("ondestory")
  25. }
  26. public fun log(msg:String)
  27. {
  28. Log.e(TAG,"${msg}")
  29. }
  30. }
2、BaseViewModel
  1. abstract open class BaseViewModel(val context: Application) : AndroidViewModel(context),
  2. BaseViewModelLifecycleObserver {
  3. }
3、定义业务的ViewModel
  1. class MyViewModel(context: Application) : BaseViewModel(context) {
  2. private val model: MyModel by lazy { MyModel() }
  3. public val initLiveData: MutableLiveData<String> by lazy { MutableLiveData() }
  4. public fun showToast(msg: String) {
  5. Toast.makeText(getApplication(), msg, Toast.LENGTH_SHORT).show()
  6. }
  7. public fun initData() {
  8. val data=model.getInitData()
  9. initLiveData.value=data
  10. }
  11. }

这里面多了一个MutableLiveData,就是数据回传的订阅,ViewModel发送了数据给View通过LiveData进行订阅。在这里面要创建Model对象

创建

创建这里面涉及到了kotlin的泛型问题,相比Java,kotlin的泛型比较复杂,由于创建是和DataBinding绑在一起的,这边先介绍泛型的创建与生命周期的绑定

  1. val type = javaClass.genericSuperclass
  2. if (type != null && type is ParameterizedType) {
  3. val actualTypeArguments = type.actualTypeArguments
  4. val tClass = actualTypeArguments[1]
  5. viewModel= AndroidViewModelFactory.getInstance(application).create(tClass as Class<V>)
  6. }
  7. lifecycle.addObserver(viewModel)

    lifecycle.addObserver(viewModel):绑定了当前的生命周期

注意:在需要消费,否则导致内存泄露
  1. override fun onDestroy() {
  2. super.onDestroy()
  3. lifecycle.removeObserver(viewModel)
  4. }

View模块

View模块主要就是DataBinding的创建与ViewMOdel的创建,ViewModel上面已介绍如何创建,下面将介绍如何去架构这个基础页面,去管理

这边架构的页面分为两个类:第一个是DataBinding类,还有一个是DataBinding与ViewModel继承类,为什么要分开?因为在正常业务中,有些模块不需要ViewModel,但是DataBinding是必须使用,所以只需要继承DataBinding类即可。

DataBinding基础类:
 
  1. open abstract class BaseDataBindModelActivity<T : ViewDataBinding>() : FragmentActivity() {
  2. public lateinit var binding: T
  3. //配置当前页面布局资源
  4. @LayoutRes
  5. public abstract fun getLayoutResId(): Int
  6. override fun onCreate(savedInstanceState: Bundle?) {
  7. super.onCreate(savedInstanceState)
  8. binding = DataBindingUtil.setContentView<T>(this, getLayoutResId())
  9. initViewModel()
  10. initObser()
  11. initDataBeforInitView()
  12. initVie()
  13. initDataAfterInitView()
  14. }
  15. //初始化viewmodel
  16. open protected fun initViewModel() {
  17. }
  18. //初始化页面
  19. abstract fun initVie()
  20. //初始化livedata的监听,
  21. abstract fun initObser()
  22. //获取数据在initview之前
  23. abstract fun initDataBeforInitView()
  24. //获取数据在initview之后
  25. abstract fun initDataAfterInitView()
  26. //页面消费之前,解绑
  27. override fun onDestroy() {
  28. if (binding != null) {
  29. binding.unbind()
  30. }
  31. super.onDestroy()
  32. }
  33. }

ViewModelDataBinding基础类:

  1. abstract class BaseViewModelBindActivity<T : ViewDataBinding, V : BaseViewModel>() :
  2. BaseDataBindModelActivity<T>() {
  3. lateinit var viewModel: V
  4. override fun initViewModel() {
  5. super.initViewModel()
  6. val type = javaClass.genericSuperclass
  7. if (type != null && type is ParameterizedType) {
  8. val actualTypeArguments = type.actualTypeArguments
  9. val tClass = actualTypeArguments[1]
  10. viewModel= AndroidViewModelFactory.getInstance(application).create(tClass as Class<V>)
  11. }
  12. lifecycle.addObserver(viewModel)
  13. }
  14. override fun onDestroy() {
  15. super.onDestroy()
  16. lifecycle.removeObserver(viewModel)
  17. }
  18. }

通过以上的配置,基本已完成了MVVM的搭建。

小时牛刀:

  1. class MyTestViewBindActivity : BaseViewModelBindActivity<TestViewBind, MyViewModel>() {
  2. override fun getLayoutResId(): Int {
  3. return R.layout.layout_test_view_bind
  4. }
  5. override fun initVie() {
  6. binding.btnTest.setOnClickListener {
  7. viewModel.showToast("你好")
  8. }
  9. binding.btnInit.setOnClickListener {
  10. //调用了初始化事件
  11. viewModel.initData()
  12. }
  13. }
  14. override fun initObser() {
  15. //数据订阅事件
  16. viewModel.initLiveData.observe(this) {
  17. binding.textInfo.text = it
  18. }
  19. }
  20. override fun initDataBeforInitView() {
  21. }
  22. override fun initDataAfterInitView() {
  23. }
  24. }

绑定的页面生命周期回调:

运行效果

五、总结

1.通过以上学习,完成了MVVM的基础结构与如何架构一个MVVM页面出来。Demo中也基本完成了大家的难点问题。

2.如果不了解生命周期的可以参考Demo中直接拿去用,避免处理不好导致内存泄露

3.MVVM需要databinding的参与,如果不了解的小伙伴直接看我的DataBinding文章,看完直接上项目使用是没任何问题,有问题我得文章中也会提出,这边都是干货,都是博主自己总结与写出来的。希望大家能够受益。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/418874
推荐阅读
相关标签
  

闽ICP备14008679号