皮皮网

【hadoop avatar 源码】【app代码源码学习】【客服系统源码搭建】android mvvm源码

时间:2024-12-26 13:42:50 分类:探索 来源:vb简单源码

1.Android UI 架构演进:从 MVC 到 MVP、MVVM、MVI
2.AndroidMVVM
3.Android篇MVVM 到 MVI:迁移 Android 架构
4.androidui设计mvvm设计模式讨论?
5.Android mvvm 之 databinding 原理
6.Android-MVVM-Databinding的原理、用法与封装

android mvvm源码

Android UI 架构演进:从 MVC 到 MVP、MVVM、MVI

       Android UI架构的hadoop avatar 源码演变:从MVC到MVP、MVVM和MVI

       随着Android开发的发展,为优化代码设计,业界不断探索和实践不同的架构模式,如MVC、MVP、MVVM和MVI,它们的核心目标是“关注点分离”,以提高代码的可维护性、测试性和可读性。最初,所有UI逻辑都集中在Activity中,导致高度耦合,难以管理。

       1. MVC:Android的默认设计,将代码划分为Model、View和Controller,尽管解决了Activity代码过载问题,但Activity仍承担了View和逻辑处理的双重任务,分离不够彻底。

       2. MVP:为了解决MVC的不足,MVP将逻辑分离到Presenter,app代码源码学习使用Contract接口定义View和Presenter的交互。但双向依赖仍是其缺点。

       3. MVVM:MVVM将Presenter变为ViewModel,使用观察者模式减少双向依赖。DataBinding等工具支持了MVVM的实现,但过度使用可能导致数据流混乱。

       4. MVI:MVI强调单数据流,通过ViewState简化View和ViewModel之间的交互。虽然更注重响应式,但过度压缩状态可能导致复杂性。

       总的来说,MVP、MVVM和MVI都试图将Activity的职责分解,但每种模式都有其局限性和适用场景。MVVM和MVP本质上相似,而MVI则引入了命令式到响应式的转变。选择哪种架构,应根据项目的具体需求和团队习惯来决定,而不是盲目追求新潮。

AndroidMVVM

       æ¦‚è¿°

       è¯´åˆ°Android MVVM,相信大家都会想到Google 年推出的DataBinding框架。然而两者的概念是不一样的,不能混为一谈。MVVM是一种架构模式,而DataBinding是一个实现数据和UI绑定的框架,是构建MVVM模式的一个工具。

       ä¹‹å‰çœ‹è¿‡å¾ˆå¤šå…³äºŽAndroid MVVM的博客,但大多数提到的都是DataBinding的基本用法,很少有文章仔细讲解在Android中是如何通过DataBinding去构建MVVM的应用框架的。View、ViewModel、Model每一层的职责如何?它们之间联系怎样、分工如何、代码应该如何设计?这是我写这篇文章的初衷。

       æŽ¥ä¸‹æ¥ï¼Œæˆ‘们先来看看什么是MVVM,然后再一步一步来设计整个MVVM框架。

       MVC、MVP、MVVM

       é¦–先,我们先大致了解下Android开发中常见的模式。

       MVC

       View:XML布局文件。

       Model:实体模型(数据的获取、存储、数据状态变化)。

       Controllor:对应于Activity,处理数据、业务和UI。

       ä»Žä¸Šé¢è¿™ä¸ªç»“构来看,Android本身的设计还是符合MVC架构的,但是Android中纯粹作为View的XML视图功能太弱,我们大量处理View的逻辑只能写在Activity中,这样Activity就充当了View和Controller两个角色,直接导致Activity中的代码大爆炸。相信大多数Android开发者都遇到过一个Acitivty数以千行的代码情况吧!所以,更贴切的说法是,这个MVC结构最终其实只是一个Model-View(Activity:View&Controller)的结构。

       MVP

       View: 对应于Activity和XML,负责View的绘制以及与用户的交互。

       Model: 依然是实体模型。

       Presenter: 负责完成View与Model间的交互和业务逻辑。

       å‰é¢æˆ‘们说,Activity充当了View和Controller两个角色,MVP就能很好地解决这个问题,其核心理念是通过一个抽象的View接口(不是真正的View层)将Presenter与真正的View层进行解耦。Persenter持有该View接口,对该接口进行操作,而不是直接操作View层。这样就可以把视图操作和业务逻辑解耦,从而让Activity成为真正的View层。

       ä½†MVP也存在一些弊端:

       Presenter(以下简称P)层与View(以下简称V)层是通过接口进行交互的,接口粒度不好控制。粒度太小,就会存在大量接口的情况,使代码太过碎版化;粒度太大,解耦效果不好。同时对于UI的输入和数据的变化,需要手动调用V层或者P层相关的接口,相对来说缺乏自动性、监听性。如果数据的变化能自动响应到UI、UI的输入能自动更新到数据,那该多好!

       MVP是以UI为驱动的模型,更新UI都需要保证能获取到控件的引用,同时更新UI的时候要考虑当前是否是UI线程,也要考虑Activity的生命周期(是否已经销毁等)。

       MVP是以UI和事件为驱动的传统模型,数据都是被动地通过UI控件做展示,但是由于数据的时变性,我们更希望数据能转被动为主动,希望数据能更有活性,由数据来驱动UI。

       V层与P层还是有一定的耦合度。一旦V层某个UI元素更改,那么对应的接口就必须得改,数据如何映射到UI上、事件监听接口这些都需要转变,牵一发而动全身。如果这一层也能解耦就更好了。

       å¤æ‚的业务同时也可能会导致P层太大,代码臃肿的问题依然不能解决。

       MVVM

       View: 对应于Activity和XML,负责View的绘制以及与用户交互。

       Model: 实体模型。

       ViewModel: 负责完成View与Model间的交互,负责业务逻辑。

       MVVM的目标和思想与MVP类似,利用数据绑定(Data Binding)、依赖属性(Dependency Property)、命令(Command)、路由事件(Routed Event)等新特性,打造了一个更加灵活高效的架构。

       æ•°æ®é©±åŠ¨

       åœ¨å¸¸è§„的开发模式中,数据变化需要更新UI的时候,需要先获取UI控件的引用,然后再更新UI。获取用户的输入和操作也需要通过UI控件的引用。在MVVM中,这些都是通过数据驱动来自动完成的,数据变化后会自动更新UI,UI的改变也能自动反馈到数据层,数据成为主导因素。这样MVVM层在业务逻辑处理中只要关心数据,不需要直接和UI打交道,在业务处理过程中简单方便很多。

       ä½Žè€¦åˆåº¦

       MVVM模式中,数据是独立于UI的。

       æ•°æ®å’Œä¸šåŠ¡é€»è¾‘处于一个独立的ViewModel中,ViewModel只需要关注数据和业务逻辑,不需要和UI或者控件打交道。UI想怎么处理数据都由UI自己决定,ViewModel不涉及任何和UI相关的事,也不持有UI控件的引用。即便是控件改变了(比如:TextView换成EditText),ViewModel也几乎不需要更改任何代码。它非常完美的解耦了View层和ViewModel,解决了上面我们所说的MVP的痛点。

       æ›´æ–°UI

       åœ¨MVVM中,数据发生变化后,我们在工作线程直接修改(在数据是线程安全的情况下)ViewModel的数据即可,不用再考虑要切到主线程更新UI了,这些事情相关框架都帮我们做了。

       å›¢é˜Ÿåä½œ

       MVVM的分工是非常明显的,由于View和ViewModel之间是松散耦合的:一个是处理业务和数据、一个是专门的UI处理。所以,完全由两个人分工来做,一个做UI(XML和Activity)一个写ViewModel,效率更高。

       å¯å¤ç”¨æ€§

       ä¸€ä¸ªViewModel可以复用到多个View中。同样的一份数据,可以提供给不同的UI去做展示。对于版本迭代中频繁的UI改动,更新或新增一套View即可。如果想在UI上做A/B Testing,那MVVM是你不二选择。

       å•å…ƒæµ‹è¯•

       æœ‰äº›åŒå­¦ä¸€çœ‹åˆ°å•å…ƒæµ‹è¯•ï¼Œå¯èƒ½è„‘袋都大。是啊,写成一团浆糊的代码怎么可能做单元测试?如果你们以代码太烂无法写单元测试而逃避,那可真是不好的消息了。这时候,你需要MVVM来拯救。

       æˆ‘们前面说过了,ViewModel层做的事是数据处理和业务逻辑,View层中关注的是UI,两者完全没有依赖。不管是UI的单元测试还是业务逻辑的单元测试,都是低耦合的。在MVVM中数据是直接绑定到UI控件上的(部分数据是可以直接反映出UI上的内容),那么我们就可以直接通过修改绑定的数据源来间接做一些Android UI上的测试。

       é€šè¿‡ä¸Šé¢çš„简述以及模式的对比,我们可以发现MVVM的优势还是非常明显的。虽然目前Android开发中可能真正在使用MVVM的很少,但是值得我们去做一些探讨和调研。

       å¦‚何构建MVVM应用框架

       å¦‚何分工

       æž„建MVVM框架首先要具体了解各个模块的分工。接下来我们来讲解View、ViewModel、Model它们各自的职责所在。

       View

       View层做的就是和UI相关的工作,我们只在XML、Activity和Fragment写View层的代码,View层不做和业务相关的事,也就是我们在Activity不写业务逻辑和业务数据相关的代码,更新UI通过数据绑定实现,尽量在ViewModel里面做(更新绑定的数据源即可),Activity要做的事就是初始化一些控件(如控件的颜色,添加的分割线),View层可以提供更新UI的接口(但是我们更倾向所有的UI元素都是通过数据来驱动更改UI),View层可以处理事件(但是我们更希望UI事件通过Command来绑定)。简单地说:View层不做任何业务逻辑、不涉及操作数据、不处理数据,UI和数据严格的分开。

       ViewModel

       ViewModel层做的事情刚好和View层相反,ViewModel只做和业务逻辑和业务数据相关的事,不做任何和UI相关的事情,ViewModel 层不会持有任何控件的引用,更不会在ViewModel中通过UI控件的引用去做更新UI的事情。ViewModel就是专注于业务的逻辑处理,做的事情也都只是对数据的操作(这些数据绑定在相应的控件上会自动去更改UI)。同时DataBinding框架已经支持双向绑定,让我们可以通过双向绑定获取View层反馈给ViewModel层的数据,并对这些数据上进行操作。关于对UI控件事件的处理,我们也希望能把这些事件处理绑定到控件上,并把这些事件的处理统一化,为此我们通过对一些常用的事件做了封装,把一个个事件封装成一个个Command,对于每个事件我们用一个去处理就行了,会把你可能需要的数据带给你,这使得我们在ViewModel层处理事件的时候只需要关心处理数据就行了,具体见MVVM Light Toolkit 使用指南的 Command 部分。再强调一遍:ViewModel 不做和UI相关的事。

       Model

       Model层最大的特点是被赋予了数据获取的职责,与我们平常Model层只定义实体对象的行为截然不同。实例中,数据的获取、存储、数据状态变化都是Model层的任务。Model包括实体模型(Bean)、Retrofit的Service ,获取网络数据接口,本地存储(增删改查)接口,数据变化监听等。Model提供数据获取接口供ViewModel调用,经数据转换和操作并最终映射绑定到View层某个UI元素的属性上。

       å¦‚何协作

       å…³äºŽåä½œï¼Œæˆ‘们先来看下面的一张图:

       ä¸Šå›¾åæ˜ äº†MVVM框架中各个模块的联系和数据流的走向,我们从每个模块一一拆分来看。那么我们重点就是下面的三个协作。

       ViewModel与View的协作。

       ViewModel与Model的协作。

       ViewModel与ViewModel的协作。

       ViewModel与View的协作

       å›¾2中ViewModel和View是通过绑定的方式连接在一起的,绑定分成两种:一种是数据绑定,一种是命令绑定。数据的绑定DataBinding已经提供好了,简单地定义一些就能把数据和控件绑定在一起了(如TextView的text属性),但是DataBinding框架提供的不够全面,比如说如何让一个URL绑定到一个ImageView,让这个ImageView能自动去加载url指定的图片,如何把数据源和布局模板绑定到一个ListView,让ListView可以不需要去写Adapter和ViewHolder相关的东西?这些就需要我们做一些工作和简单的封装。MVVM Light Toolkit 已经帮我们做了一部分的工作,详情可以查看MVVM Light Toolkit 使用指南。关于事件绑定也是一样,MVVM Light Toolkit 做了简单的封装,对于每个事件我们用一个去处理就行了,会把可能需要的数据带给你,这样我们处理事件的时候也只关心处理数据就行了。

       ç”±å›¾1中ViewModel的模块中我们可以看出ViewModel类下面一般包含下面5个部分:

       Context (上下文)

       Model (数据源 Java Bean)

       Data Field (数据绑定)

       Command (命令绑定)

       Child ViewModel (子ViewModel)

       æˆ‘们先来看下示例代码,然后再一一讲解5个部分是干嘛用的:

       // Activity context;//model(数据源 Java Bean)private NewsService.News news;private .News topNews;//数据绑定,绑定到UI的字段(data field)public final imageUrl = new ();public final html = new ();public final title = new ();// 一个变量包含了所有关于View Style 相关的字段public final ViewStyle viewStyle = new ViewStyle();//命令绑定(command)public finalonRefreshCommand = new ReplyCommand(() -> {

       })public final ReplyCommand onLoadMoreCommand = new ReplyCommand((itemCount) -> {

       });//Child ViewModelpublic final ObservableList itemViewModel = new ObservableArrayList();/** * ViewStyle 关于控件的一些属性和业务数据无关的Style 可以做一个包裹,这样代码比较美观,

       ViewModel 页面也不会有太多太杂的字段。 **/public static class ViewStyle {

       public final ObservableBoolean isRefreshing = new ObservableBoolean(true);

       public final ObservableBoolean progressRefreshing = new ObservableBoolean(true);

       }

       Context

Android篇MVVM 到 MVI:迁移 Android 架构

       迁移至 Model-View-Intent (MVI) 架构可能看似挑战重重,然而,其清晰的架构设计和预测性强的应用程序行为,使得这一转变显得尤为必要。

       本文将深入解析 MVVM 与 MVI 之间的差异,并详细阐述如何实现 MVI 迁移。

       MVVM 与 MVI

       在移动应用开发领域,客服系统源码搭建MVVM 架构备受青睐。它通过将用户界面(View)与数据逻辑(ViewModel)分离,实现数据绑定的灵活应用。ViewModel 负责为 View 准备数据,并处理用户输入。

       与之相比,MVI 架构作为近年来兴起的新模式,同样实现 View 与数据的分离。然而,它引入了名为 Intent 的新层,该层以结构化和可预测的方式表示用户操作,并将 Intent 传递给 Model。Model 根据Intent 产生新的状态,并在 View 中展示。

       这两种架构的关键区别在于,在 MVVM 中,ViewModel 负责用户操作和更新 View 的状态。而在 MVI 中,Intent 作为独立的层,表示用户操作,使应用程序行为易于推断,同时便于处理边缘情况。

       为什么选择 MVI?如何从 MVVM 迁移到 MVI?

       从 MVVM 迁移至 MVI 虽然看似艰巨,实则是一个逐步的过程。以下是一些关键步骤:

       步骤1:创建 Intent 类

       步骤2:更新 ViewModel

       步骤3:更新 Model

       步骤4:更新 View

       通过遵循上述步骤,您可以将现有的订阅功能源码 MVVM 架构逐步迁移至 MVI 架构,从而实现关注点分离、预测性强和可测试性高的应用程序。

androidui设计mvvm设计模式讨论?

       讨论MVVM设计模式

       在讨论中,参与者提到MVC和MVP在控制层的控制力上有显著差别。MVC模式在上世纪年代出现,经过三十多年的发展,演化出多种变种,包括MVP。然而,在Android开发中,Activity代码量庞大,往往需要承担过多职责,这主要是由于视图功能较弱导致。因此,有观点认为MVP优于MVC,它提供更强大的控制层,能最大程度上分担Activity中的逻辑工作。具体实现和详细思考可在相关博客中找到。

       进一步,MVVM被视为MVP的升级版。在MVVM中,ViewModel结合了View的数据模型和Presenter的功能,通过Data Binding进行View和控制层间的交互,实现双向交互,降低耦合度,促进关注点分离,obd小程序源码减轻Activity的负担。在VM中,每个页面的数据模型只有一套,但Presenter应根据逻辑拆分。

       相关资源推荐:Data Binding Guide、对MVC、MVP、MVVM的理解、Data Binding 用户指南(Android)

Android mvvm 之 databinding 原理

       文本为原创内容,转载请注明出处——小舍

       目录

       1. Data Binding 的结构 [Top]

       Data Binding 是在 Android 开发中体现 MVVM 架构思想的重要组件,其核心是观察者模式的实现。其功能主要集中在三个方面:

        1.1 rebind 行为:Data Binding 通过将整个 Data 集合绑定到 View,实现数据的整体更新。例如,初始化和数据的整体更新可通过简单的赋值操作实现,由代理类 ViewDataBinding 完成。

        1.2 observe data 行为:允许 View 观察 Data 的行为变化,仅更新需要的数据成员。通过将 Data 设置为 Observable,ViewDataBinding 作为代理观察者订阅 Data 的成员变化,实现精准的数据绑定。

        1.3 observe view 行为:针对业务需求,实现 View 的单工和双工行为。单工View仅需 observe data 行为,而双工View则需同时实现 observe data 和 observe view 行为,以保证数据的一致性。

       2. 样例分析——谷歌 sunflower 的改造 [Top]

       sunflower app 是谷歌推荐的 jetpack 库应用的最佳实践,这里通过修改植物种植详情页面的实现,分析 observe view 行为。关键在于定义数据类 FakeData、布局文件 fragment_plant_detail.xml 和 ViewDataBinding 类 FragmentPlantDetailBinding。

       2.1 Data——FakeData:定义了数据类 FakeData,包括两个成员。通过 observe data 行为,实现数据与 View 的精准绑定。

       2.2 View——fragment_plant_detail.xml:布局文件中使用 @BindingAdapter 标注,实现数据与 View 节点的绑定。

       2.3 ViewDataBinding——FragmentPlantDetailBinding:作为业务层的接口,实现读取 View 节点和 Data。结合观察者模式原理,实现数据到 View 的动态绑定。

       3. 免 findViewById 的实现 [Top]

       在暴露给业务层的 ViewDataBinding 类中,保存了布局文件中 View 节点的引用,通过观察者模式原理,实现免 findViewById 的动态绑定。主要流程包括读取 View 节点引用和数据成员引用两大部分。该文档参考的 androidx 版本为 core: 1.1.0。

Android-MVVM-Databinding的原理、用法与封装

       Android-MVVM-Databinding,这个官方推荐的架构,尽管历经起落,但作为XML布局的主要解决方案,仍然具有其必要性。开发者们常常对它持有负面印象,认为它过时、更新缓慢且存在诸多缺点。然而,随着MVVM架构的流行,DataBinding作为其关键组件,学习和理解其原理、用法与封装变得至关重要。

       传统 findViewById 方法存在性能问题,当布局复杂时,代码冗余且容易出错。DataBinding和ViewBinding的出现,旨在简化这一过程。ViewBinding甚至提供了编译时的空指针检查,而DataBinding则提供了双向绑定和XML变量等功能。尽管Kotlin-android-extensions曾让DataBinding在Kotlin项目中消失,但ViewBinding的出现让它重获关注。

       使用DataBinding,无需手动导入依赖,只需配置后,XML布局可通过DataBindingLayout转换。变量和事件处理变得直观,比如双向绑定,使得UI与数据同步更为便捷。然而,实际开发中,还需注意如RV.Adapter中的使用、自定义View和属性处理等高级技巧,这些都有助于避免常见问题。

       尽管DataBinding在某些场景下可能较为复杂,封装和优化可以简化常用操作。例如,Activity/Fragment主页面的封装,以及RV.Adapter的定制化。总的来说,DataBinding与MVVM的结合提供了更安全、更高效的UI管理,尽管未来可能被Compose取代,但在目前,掌握DataBinding仍是Android开发的必要技能。

       学习建议包括理解双向绑定的优势,考虑同时使用ViewBinding以减少编译时的体积,以及注意性能优化,避免在XML中过多的逻辑处理。同时,关注BindingAdapter的使用,可以帮助简化数据绑定和监听设置。掌握DataBinding,对当前和未来的Android项目开发都大有裨益。

       相关学习资源:[Android 学习链接]

听说这套框架可以搞定 Android MVI

       前言

       没有最完美的架构,只有最合适的架构。

       Android应用架构变迁:MVC、MVP、MVVM、MVI。

       关于这四种架构的概念、逻辑、实现方式与优劣,技术社区内优质文章不胜枚举,此处不再赘述。

       今天重点介绍如何利用Airbnb开源框架Mavericks快速实践MVI架构。

       主要弄清楚下面几个问题:

       Mavericks(MvRx): Android on Autopilot

       Mavericks是Aribnb开源的一款功能强大且易于学习的AndroidMVI框架。Mavericks以AndroidJetpack和KotlinCoroutines为基础搭建上层逻辑,在技术先进性和可持续方面毋庸置疑。至于框架实用性,相信接受了Airbnb、Tonal等大型APP长时间检验的Mavericks,不会让开发者失望。

       核心概念

       一个简单的计数界面只需要下面几行代码,既清晰又简洁。

       实践

       需求:利用WanAndroidAPI[1]实现搜索热词的列表展示(支持下拉刷新)

       接口:/hotkey/json

       1. 依赖2. 初始化

       Application内onCreate()函数中执行初始化。

       3. MavericksState

       定义MainState并添加两个属性:

       4. MavericksViewModel

       定义MainViewModel管理MainState,实现获取搜索热词函数。

       5. MavericksView

       创建MainFragment并实现MavericksView接口用于展示搜索热词列表,用户可以下拉刷新请求新数据。

       6. 效果源码

       Talk is cheap,Show me the code。

       /onlyloveyd/AndroidSamples

       划重点

       1. Async异步处理密封类,有四个子类:Uninitialized、Loading、Success、Fail,分别代表异步处理的4种状态。

       2. onAsync异步属性状态变化监听

       3. retainValue加载过程中或者加载失败后显示的数据。

       示例中,我们将getHotKeys()函数内的retainValue去掉,界面更新数据时会有明显的闪动。

       4. 监听模式:DeliveryMode

       5. 状态监听防止崩溃

       为了防止回调时界面已经被销毁而导致程序奔溃,采用launchWhenStarted防御策略。

       总结

       简单好用,是选轮子的基本标准。

       上手Mavericks后,感觉代码层次清晰,集成方便,简单易用,符合好轮子的标准。

       对于鄙人这种不太爱自己折腾框架的躺平者而言,简直福音。下一步准备把之前写的WanAndroidClient用Mavericks改写下。

copyright © 2016 powered by 皮皮网   sitemap