MVVM 架构,ViewModel和LiveData(一)

MVVM 架构,ViewModel和LiveData(一)

标签(空格分隔): 翻译计划 Android开发


原文链接

  • MVVM architecture, ViewModel and LiveData (Part 1)

正文

在Google I/O之间,Google推出了包含LiveData和ViewModel的组件架构,这有助于开发者们使用MVVM开发Android应用程序。这篇文章旨在讲述该组件如何融汇在使用MVVM模式开发Android应用程序。

MVVM简单介绍

如果你很熟悉MVVM架构,那么你可以快速跳过本小节知识点。

MVVM是增强关注点分离的体系结构模式之一,它允许将用户界面逻辑从业务(或者后端)逻辑中分离开来,他的目标(和MVC等其他目标)是为了实现”保持UI代码简单化,不涉及更多的业务逻辑,以便于开发者更好的控制和管理”。

MVVM主要有以下几个层次:

  • 1、Model层
    • Model层表示用户程序的数据和业务逻辑,这一层的的推荐的实现策略之一就是观测数据的变化并传递出去(供谁使用),使其从ViewModel或者其他观察者/消费者中完全解耦.(这将在我们文章下面的MVVM事例中进行说明).
  • 2、ViewModel层
    • ViewModel是和Model(数据层)进行交互,并且ViewMode可以被View观察.ViewModel可以选择性地为视图提供钩子以将事件传递给模型.该层的一个重要实现策略是将Model与View分离,即ViewModel不应该意识到与谁交互的视图.
  • 3、View层
    • 此模式中的视图角色是观察(或订阅)ViewMode,观察数据b变化,以便于获取数据去更新UI元素.

下图显示了MVVM组件和基本交互。
MVVM.png

LiveData

如上所述,LiveData是新引入的组件架构之一,LiveData是一个可以被观察的数据持有者.这也就意味着应用中的组件能够观察LiveData对象的更改,而无需在它们之间创建明确的和严格的依赖关系。这将完全分离LiveData对象使用者和LiveData对象生产者。

除此之外,LiveData还有一个很大的好处,LiveData遵守应用程序组件(活动,片段,服务)的生命周期状态,并进组件的生命周期管理,确保LiveData对象的内存泄漏.

根据Google文档,如果您已经在使用Rx或Agera等开源库,那么你可以继续使用它们而不是替换成LiveData.但在这种情况下,您有责任处理每个Android组件生命周期的对象分配和解除分配.

由于LiveData遵从Android的生命周期机制,这意味着除非LiveData主体(activity或fragment)处于活动状态(接收onStart()但未收到onStop()),否则它将不会调用其观察者回调.除此之外,当主体收到onDestroy()时,LiveData也会自动删除观察者防止内存泄漏.

LiveData也会将在下面的MVVM事例中进行说明.

ViewModel

ViewModel也是新引入的体系架构组件之一.架构组件提供了一个名为ViewModel的新类,它负责为UI / View准备数据.

ViewModel为您的MVVM模式中的ViewModel提供了一个很好的基类,因为ViewModel(及其子类AndroidViewModel)的扩展类会在配置更改期间自动保留其数据.这意味着,在配置更改后,此ViewModel所有数据可立即用于下一个活动(activity)或片段(fragment)实例.

下图显示了ViewModel组件的生命周期:
The life cycle of ViewModel component

ViewModel也将会在下面的MVVM事例中进行说明。

应用事例

现在,让我们来看看最有趣的部分,让我们把上述的所有知识(组件)放在一个程序中.
此MVVM事例应用主要包含两个界面.
下面显示的第一个界面显示了Google GitHub上的项目列表.其中包含一些简要信息,例如标题,编程语言和watcher数量。
image.png

一旦用户点击了首页的item,GitHub项目的详细信息屏幕将会显示项目描述,编程语言,watcher数量,公开问题,创建和上次更新日期,最后显示克隆URL.

image.png

示例应用程序交互图

下图显示了示例应用程序的包结构

image.png

以下交互图显示了检索Google GitHub项目的应用场景之一的示例交互图。
image.png

如上图所示,每个图层都从其后续图层(Fragment(View) - > ViewModel - > Repository)观察LiveData,最后一旦检索到项目列表(或者有所变化),就会使用RecyclerView(ListView)适配器绑定显示项目列表.

Respository模块负责处理数据操作,通过这一点,Respository可以为程序的其余部分提供干净的API,并简化ViewModel的工作.
如果需要更新数据,Respository模块应该知道从哪里获取数据以及进行哪些API调用.它们可以被视为不同数据源(REST服务,数据库,XML文件等)之间的中介.

现在,让我们从下往上解释这些图层,从Model、ViewModel开始,最后用View来检索GitHub项目场景。

示例应用程序模型层

让我们从业务逻辑层开始,我们有两个模型对象

  • 1、Project.包含GitHub项目的信息,如id,名称,描述,创建日期等等
  • 2、User,包含GitHub项目所有者的用户信息.
    为了与GitHub RESTful API进行交互,我使用了我喜欢的Retrofit2来定义存储库包中的以下简单接口。
interface GitHubService {String HTTPS_API_GITHUB_URL = "https://api.github.com/";@GET("users/{user}/repos")Call<List<Project>> getProjectList(@Path("user") String user);@GET("/repos/{user}/{reponame}")Call<Project> getProjectDetails(@Path("user") String user, @Path("reponame") String projectName);
}

为了便于ViewModel的工作,创建一个ProjectRespository来与GitHub服务交互,并最终为ViewModel提供一个LiveData对象.以下代码片段显示了getProjectList()API实现.

public class ProjectRepository {private GitHubService gitHubService;//…public LiveData<List<Project>> getProjectList(String userId) {final MutableLiveData<List<Project>> data = new MutableLiveData<>();gitHubService.getProjectList(userId).enqueue(new Callback<List<Project>>() {@Overridepublic void onResponse(Call<List<Project>> call, Response<List<Project>> response) {data.setValue(response.body());}// Error handling will be explained in the next article …});return data;}// …
}

ProjectRepository是ViewModel的数据提供者,它有getProjectList(),它简单地将响应包装到LiveData对象中.

为了简化本文的目的,错误处理被省略,并且将在下一篇文章中进行说明

示例应用程序ViewModel层

为了处理(接收)getProjectList()API,创建了ViewModel类(调用Repository API并可以为LiveData执行任何所需的数据转换).
以下代码片段显示了ProjectListViewModel类

public class ProjectListViewModel extends AndroidViewModel {private final LiveData<List<Project>> projectListObservable;public ProjectListViewModel(Application application) {super(application);// If any transformation is needed, this can be simply done by Transformations class ...projectListObservable = ProjectRepository.getInstance().getProjectList("Google");}/*** Expose the LiveData Projects query so the UI can observe it.*/public LiveData<List<Project>> getProjectListObservable() {return projectListObservable;}
}

如上所示,我们的ProjectListViewModel类继承了AndroidViewModel,并在构造函数中调用getProjectList(“Google”)来检索Google GitHub项目.

在现实世界的情况下,在将结果数据传递到观察视图之前可能需要进行转换,为了进行转换,可以使用Transformation类,如以下文档中所示https://developer.android.com/topic/libraries/architecture/livedata.html#transformations_of_livedata

示例应用视图图层View

最后,让我们快速浏览一下这个应用程序的视图层,我们主要有一个名为MainActivity的Activity(活动),它负责处理代表应用程序视图的两个片段的导航.

  • 1、ProjectListFragment:其中显示了Google GitHub项目的列表界面
  • 2、ProjectFragment:它显示所选的GitHub项目详细信息

由于活动和片段被视为生命周期所有者,activity需要扩展LifecycleActivity,fragment需要扩展LifecycleFragment.但是,请务必记住LifecycleActivity和LifecycleFragment类都是临时实现,直到Lifecycle与支持库支持为止:https://developer.android.com/reference/android/arch/lifecycle/LifecycleActivity.html

现在,让我们继续我们的项目检索方案,查看ProjectListFragment这个界面,下面的代码片段显示了最重要的集成部分.

public class ProjectListFragment extends LifecycleFragment {private ProjectAdapter projectAdapter;//…@Overridepublic void onActivityCreated(@Nullable Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);final ProjectListViewModel viewModel =ViewModelProviders.of(this).get(ProjectListViewModel.class);observeViewModel(viewModel);}private void observeViewModel(ProjectListViewModel viewModel) {// Update the list when the data changesviewModel.getProjectListObservable().observe(this, new Observer<List<Project>>() {@Overridepublic void onChanged(@Nullable List<Project> projects) {if (projects != null) {//…projectAdapter.setProjectList(projects);}}});}//…
}

如上代码所示,ProjectListFragment获取ProjectListViewModel数据对象,然后监听其getProjectListObservable()方法,以便获取Github项目列表。
最后,一旦检索到项目列表(有数据变化),它将被传递给projectAdapter(RecyclerView适配器),以显示RecyclerView组件中(更新UI).

这是对项目的一个端到端场景的解释,您可以在这里找到GitHub中提供的完整项目:

  • https://github.com/hazems/mvvm-sample-app/tree/part1

MVVM模式的重要指导原则

现在,重点介绍MVVM实现的一些重要指导原则:

  • 1、如示例中所示,ViewModels不会直接引用Views,因为如果这样做,ViewModels可能会超出View的生命周期,并且可能会发生内存泄漏
  • 2、建议Model和ViewModel中的桥梁LiveData公开其数据,因为LiveData遵守应用程序组件(活动、片段、服务)的生命周期状态并处理对象生命周期管理,以确保LiveData对象不泄漏

下一篇文章的相关知识点

故事尚未完成,因为有些事情需要处理,比如:

  • 1、Dependency Injection(依赖注入)
  • 2、Error Handling(错误处理)
  • 3、Caching(缓存)
  • 4、使用Room操作数据(数据库)
  • 5、Unit Testing(单元测试)
  • 6、Others (其他)

这将在MVVM的下一系列文章中进行说明,敬请关注.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1380532.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

DRMM model

Paper 的引用&#xff1a; Guo J, Fan Y, Ai Q, et al. A deep relevance matching model for ad-hoc retrieval[C]//Proceedings of the 25th ACM International on Conference on Information and Knowledge Management. ACM, 2016: 55-64. Retrieval or Matching 论文中说到…

JVM(JAVA虚拟机)、DVM(Dalvik虚拟机)和ART虚拟机

一、什么是DVM&#xff0c;和JVM有什么不同&#xff1f; JVM是Java Virtual Machine&#xff0c;而DVM就是Dalvik Virtual Machine&#xff0c;是安卓中使用的虚拟机&#xff0c;所有安卓程序都运行在安卓系统进程里&#xff0c;每个进程对应着一个Dalvik虚拟机实例。他们都提…

关于Hdmi2.1,FRL,DSC,VRR,ALLM你需要知道这些

文章目录 TMDSFRLDSCVRRALLM相关设备Nvidia显卡电视游戏机显示器 注意的坑 最近在研究Hdmi相关内容&#xff08;看游戏设备hhh&#xff09;&#xff0c;网上很多信息都是零零碎碎的&#xff0c;结合自己的一些研究简单记录一下。 Hdmi&#xff0c;High Definition Multimedia I…

HDMI 2.1 VRR功能详解

7.6可变刷新率和快速更新 可变刷新率&#xff08;VRR&#xff09;允许图片在源完成准备后立即通过链路发送。在链路支持的最大字符速率大于给定视频定时所需的速率的情况下&#xff0c;Fast VActive&#xff08;FVA&#xff09;减少了传输图片所需的时间。这些特性提供了性能、…

VVC帧间预测(八)DMVR

解码端运动向量修正(Decoder side motion vector refinement ,DMVR)是为了提高merge模式下双向预测MV的准确性而提出的技术。双向预测是在list0和list1中分别找一个运动向量MV0和MV1&#xff0c;然后将MV0和MV1所指向的预测块进行加权得到最终的预测块。而DMVR不是直接使用MV0和…

ARVR技术 | AR, VR, MR和XR?想搞清楚不?

AR, VR, MR&#xff0c;现在还有XR ?这些缩写是什么?它们代表什么? 让我们快速梳理一下技术术语。 首先&#xff0c;虽然你可能熟悉其中的一些术语&#xff0c;如AR和VR, 但MR和XR对许多人来说仍然是新鲜的术语。 目前的共识是&#xff0c;所有这些互补形式的现实都落在一…

MDD(模型驱动开发)

前言导读 当下企业软件应用开发面临着需求复杂多变、新的需求和系统不断增长&#xff0c;软件系统变得越来越复杂&#xff0c;普通的软件开发方式难以快速满足用户需求。为了解决这些问题&#xff0c;就出现了很多新的方法&#xff0c;其中最突出的一个就是模型驱动开发 MDD &a…

RSCMVR

也是之前发了 ~~ 又带来马教授的~~ 神器稀疏卷积性能和稳健性超越ResNet 标题就是简写可好? 尽管深度神经网络在图像分类方面具有很强的经验性能&#xff08;empirical performance&#xff09;&#xff0c;但这类模型往往被视为「黑盒」&#xff0c;最为人诟病的就是「难以解…

EMD和VMD

作者&#xff1a;桂。 时间&#xff1a;2017-03-06 20:57:22 链接&#xff1a;http://www.cnblogs.com/xingshansi/p/6511916.html 前言 本文为Hilbert变换一篇的内容补充&#xff0c;主要内容为&#xff1a; 1&#xff09;EMD原理介绍 2&#xff09;代码分析 3&#xff09…

什么是MDM

MDM或移动设备管理是一种软件应用程序&#xff0c;用于管理企业中的终端&#xff0c;如笔记本电脑、智能手机、平板电脑等。随着越来越多的员工使用这些设备&#xff0c;各种形式和规模的企业现在都转向移动设备管理&#xff0c;以增强数据安全性并提高生产力。 MDM是什么意思…

AVS3中的AMVR和EMVR

在AVS2中运动预测中使用的MV都是1/4像素精度&#xff0c;通过在整像素间插值能显著提升非整像素运动预测的精度&#xff0c;同时带来的问题是随着MV精度的提高编码MVD所需的比特数也会增加。 AMVR AMVR支持的MVD编码5种精度的MVR{1/4,1/2,1,2,4}&#xff0c;索引为0到4&#x…

无线网络视频监控系统基本概念和术语

无线网络视频监控系统基本概念和术语 1.网络摄像机与模拟摄像机的区别 模拟摄像机&#xff0c;或称摄像头&#xff0c;输出CVBS模拟视频信号&#xff0c;PAL制或者NTSC制。模拟摄像机多采用CCD器件&#xff0c;目前也有采用CMOS器件的。有枪机、半球、球机等多种形式&#xff0…

掌握Python的X篇_27_Python中标准库文档查阅方法介绍

前面的博文介绍了python的基本语法、模块及其导入方法。前人将各种方法封装成模块、库、函数供我们使用&#xff0c;如何去使用前人做好的东西&#xff0c;那就需要去查阅文档。今天就介绍python中官方文档的查阅方式。对于初学者而言&#xff0c;python自带的文档就已经足够好…

基本动态规划问题的扩展

基本动态规划问题的扩展 应用动态规划可以有效的解决许多问题&#xff0c;其中有许多问题的数学模型&#xff0c;尤其对一些自从57年就开始研究的基本问题所应用的数学模型&#xff0c;都十分精巧。有关这些问题的解法&#xff0c;我们甚至可以视为标准——也就是最优的解法。…

shell脚本安装nginx

shell脚本原理 以删除桌面文件的脚本为例&#xff0c;执行脚本后&#xff0c;shell脚本将代码给内核&#xff0c;内核读取后执行命令&#xff0c;如果shell脚本也在桌面上&#xff0c;执行后这个脚本文件也会被删除。 变量 echo $SHELL$符表示SHELL是一个变量&#xff0c;变量…

Python(七十九)字符串的常用操作——字符串内容对齐操作的方法

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

docker实现Nginx

文章目录 1.docker 安装2.docker环境实现Nginx 1.docker 安装 1.使用环境为红帽8.1,添加源 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo2.安装 yum install docker-ce docker-ce-cli containerd.io显示出错 Docker C…

Vue [Day7] 综合案例

核心概念回顾 state&#xff1a;提供数据 getters&#xff1a;提供与state相关的计算属性 mutations&#xff1a;提供方法&#xff0c;用于修改state actions&#xff1a;存放异步操作 modules&#xff1a;存模块 功能分析 https://www.npmjs.com/package/json-server#ge…

反介入/区域拒止:现代战争的演变

译者说明 本文译自美国空军Christopher J. McCarthy少校的一篇文章&#xff0c;略去了原文最后的作者简介。 原文地址&#xff08;可能需要科学上网&#xff09;&#xff1a; https://www.usnwc.edu/Lucent/OpenPdf.aspx?id95 本文仅为翻译&#xff0c;不代表译者赞成或反对原…

UE4莫名其妙崩溃的解决办法

pin error stack edgraph balabala...... 先检查蓝图把报错的节点全部去掉&#xff0c;有的运行不会提示蓝图报错&#xff0c;只能一个一个找。。。。 c报错一般都会有提示&#xff0c;所以基本都可以解决 把磁盘空间留大一点,玄学 总是在这里报错&#xff0c;这个不用管&am…