大家好,今天跟大家分享一个我开发的MVVM架构的开源小项目。
话说这个小项目已经提前跟大家预热很久了,也是被不少朋友催了很多次。我之前在公众号里透漏过这个项目能够帮助大家更好地理解MVVM架构,当然我也希望确实如此。
虽说这篇文章重点是向大家介绍这个开源小项目的,但是我并不希望就写得如此简单,我准备把它写成一篇干货文章。
一切先从Jetpack说起。我在去年年底的时候抽时间研究了下Google的Jetpack,这是一款在18年Google I/O大会上推出的Android开发组件工具集,旨在帮助我们轻松构建更稳定、更健壮、以及更可维护的应用程序。
Jetpack又引出了好几个相关联的概念,比如说Architecture Components,MVVM,它们之间是什么关系呢?
这里我先给大家做个普及,Architecture Components是Google在17年的I/O大会上推出的架构组件工具集,18年被并入到了Jetpack当中,所以严格上来讲,Architecture Components目前是Jetpack的一部分。而MVVM(Model-View-ViewModel)是一种代码架构模式,被广泛应用在Android程序设计领域,类似的架构模式还有MVP、MVC等。但是,目前Google最为推荐的代码架构模式就是MVVM,甚至Jetpack中的许多组件就是为了便于实现MVVM架构的项目而提供的。
也就是说,借助Jetpack,我们就可以轻松地编写一个MVVM架构的项目了,当然前提是你对Jetpack已经比较了解。
这里我先给出一张Jetpack的全家福:
可以看到,Jetpack主要分为4个部分,基础、架构、行为、界面。你会发现,里面有很多东西都是我们平时经常使用的,像AppCompat、通知、权限,甚至连Fragment都属于Jetpack。由此可见,Jetpack并不全是些新东西,只要是能够帮助开发者更好更方便地构建应用程序的组件,Google都将其归纳入了Jetpack。
在Jetpack这么多组件当中,其中最需要我们关注的就是架构组件了,这些是帮助我们编写出MVVM架构程序的核心。像数据绑定、Lifecycles、LiveData、Room、ViewModel等,都可以说是构建一个MVVM架构程序的重要组成部分。当然,上述组件中你并不一定要全部使用,而是可以选着使用,视自己项目的实际情况选取那些最合适的组件即可。
本篇文章我并不会带着大家一起学习Jetpack中的诸多组件,只是做个简单科普而已。可能有不少朋友还从来没接触过Jetpack,这里我贴出几个我当时用来学习的链接,大家可以适当参考一下。
ViewModels : A Simple Example https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e
Basic Example of LiveData and ViewModel https://medium.com/@taman.neupane/basic-example-of-livedata-and-viewmodel-14d5af922d0
Handling Lifecycles with Lifecycle-Aware Components https://developer.android.com/topic/libraries/architecture/lifecycle
Android lifecycle-aware components codelab https://codelabs.developers.google.com/codelabs/android-lifecycles
Build an App with Architecture Components https://codelabs.developers.google.com/codelabs/build-app-with-arch-components/index.html
上述链接中包括了Google工程师的博客、Android的官方文档、以及两个Google Codelabs项目,当然我还参考了很多其他的资料。但是当我把这些资料都看完,并且将Codelabs项目也跟着教程一步步敲出来了之后,我始终还是觉得不能融会贯通,对Jetpack以及MVVM架构的把控程度都还不够。我就意识到少了点什么,看来我得自己从头写一个MVVM的项目才行,这样才能做到对各个知识点和坑点无死角地扫描,这也是我决定做这样一个小开源项目的初衷。
确定了要做的事情之后,接下来就是思考要做一个什么样的开源项目了,有以下几个标准吧:
其实这对我来说并不难想,列出了以上几个标准之后,我一下子就想到了要做一个什么开源项目——酷欧天气Jetpack版。酷欧天气作为《第一行代码》中的经典学习项目,已经被无数小伙伴练习过,大家都是非常熟悉的。而开源这样一个项目的Jetpack版,主体功能都是保持和之前的酷欧天气版本一致的,只是里面的代码实现全部替换成了Jetpack组件和MVVM架构,这样更加可以突显出我们要关注的主题,另外也可以方便对比MVVM架构和非MVVM架构项目之间的区别。
这里我先给出一张酷欧天气Jetpack版的架构设计图,这张图是模仿Google Codelabs的Sunshine项目画出来的,上面也已经给出了这个项目的链接。拥有良好架构设计的项目都是可以用简洁清晰的架构图表示出来的,而一个杂乱无章没有架构设计的项目则很难用架构图表示出来。
上述架构图可能一开始看你会找不着重点,其实这张架构图非常清晰,我来带大家解读一下。
首先我们通过这张架构图成功将程序分为了若干层。
绿色部分表示的是UI控制层,这部分就是我们平时写的Activity和Fragment。
蓝色部分表示的是ViewModel层,ViewModel用于持有和UI元素相关的数据,以保证这些数据在屏幕旋转时不会丢失,以及负责和仓库之间进行通讯。
黄色部分表示的是仓库层,仓库层要做的工作是自主判断接口请求的数据应该是从数据库中读取还是从网络中获取,并将数据返回给调用方。如果是从网络中获取的话还要将这些数据存入到数据库当中,以避免下次重复从网络中获取。简而言之,仓库的工作就是在本地和网络数据之间做一个分配和调度的工作,调用方不管你的数据是从何而来的,我只是要从你仓库这里获取数据而已,而仓库则要自主分配如何更好更快地将数据提供给调用方。
接下来灰色部分表示是的本地数据层,实现方式并不固定,我使用了LitePal来进行数据持久化处理,你也可以使用别的框架(这里我没有使用官方的Room还是因为Room真的不太好用)。
最后红色部分表示的是网络数据层,这里使用了Retrofit从web服务接口获取数据。
借助这张架构图,我想会在很大程度上便于大家理解酷欧天气Jetpack版这个开源项目,而如果你自己编写的项目也能尝试画出这样一张架构图,那么你的代码结构一定是非常不错的。
另外对于这张架构图我还有必要再解释一下,图中所有的箭头都是单向的,比方说WeatherActivity指向了WeatherViewModel,表示WeatherActivity持有WeatherViewModel的引用,但是反过来WeatherViewModel不能持有WeatherActivity的引用。其他的几层也是一样的道理,一个箭头就表示持有一个引用。
还有,引用不能跨层持有,就比方说UI控制层不能持有仓库层的引用,每一层的组件都只能和它的相邻层交互。
大概就介绍这么多吧,剩下的就靠大家自己去阅读源码进行学习了,酷欧天气Jetpack版的开源地址是:
项目运行截图如下:
另外也请大家随手帮我点个star,多一些鼓励,我也就多一些持续贡献开源的动力。
最后,希望这个项目能够帮助大家更好地学习Jetpack,更好地学习MVVM架构。