MVVM 架构,ViewModel和LiveData
Posted 若兰明月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MVVM 架构,ViewModel和LiveData相关的知识,希望对你有一定的参考价值。
MVVM 架构,ViewModel和LiveData(一)
标签(空格分隔): 翻译计划 android开发
原文链接
正文
在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组件和基本交互。
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组件的生命周期:
ViewModel也将会在下面的MVVM事例中进行说明。
应用事例
现在,让我们来看看最有趣的部分,让我们把上述的所有知识(组件)放在一个程序中.
此MVVM事例应用主要包含两个界面.
下面显示的第一个界面显示了Google GitHub上的项目列表.其中包含一些简要信息,例如标题,编程语言和watcher数量。
一旦用户点击了首页的item,GitHub项目的详细信息屏幕将会显示项目描述,编程语言,watcher数量,公开问题,创建和上次更新日期,最后显示克隆URL.
示例应用程序交互图
下图显示了示例应用程序的包结构
以下交互图显示了检索Google GitHub项目的应用场景之一的示例交互图。
如上图所示,每个图层都从其后续图层(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>>()
@Override
public 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;
//…
@Override
public 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 changes
viewModel.getProjectListObservable().observe(this, new Observer<List<Project>>()
@Override
public void onChanged(@Nullable List<Project> projects)
if (projects != null)
//…
projectAdapter.setProjectList(projects);
);
//…
如上代码所示,ProjectListFragment获取ProjectListViewModel数据对象,然后监听其getProjectListObservable()方法,以便获取Github项目列表。
最后,一旦检索到项目列表(有数据变化),它将被传递给projectAdapter(RecyclerView适配器),以显示RecyclerView组件中(更新UI).
这是对项目的一个端到端场景的解释,您可以在这里找到GitHub中提供的完整项目:
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的下一系列文章中进行说明,敬请关注.
以上是关于MVVM 架构,ViewModel和LiveData的主要内容,如果未能解决你的问题,请参考以下文章
Android架构组件之ViewModel和LiveData
Android架构组件之ViewModel和LiveData