基于Android 端MVP 模式和响应式网络框架的设计与实现*

2021-03-11 03:48特日根
电子技术应用 2021年2期
关键词:观察者耦合度代码

李 想 ,特日根 ,3

(1.长光卫星技术有限公司,吉林 长春130000;2.吉林省卫星遥感应用技术重点实验室,吉林 长春130000;3.中国科学院长春光学精密机械与物理研究所,吉林 长春130000)

0 引言

在当今社会,移动端因其便携性、低功耗以及无线网的快速接入等优势,使得人们与外部世界进行网络连接更加方便而舒适。 正因如此,移动端编程成为了当下最热门的计算机编程领域之一。 2019 年第二季度移动端操作系统市场份额表明,Android 系统占比77.14%,iOS系统占比22.83%,其余系统不及1%,由此可知Android在当今手机行业起着举足轻重的作用。随着每一款应用承载的功能不断增多,其代码管理也变得更为复杂。 对于Android 应用开发来说,用Android Studio 编译器生成Android 项目时,其生成的XML 文件和Activity 文件已经对应传统MVC(Model-View-Controller)架构模式的View层和Controller 层, 同时XML 文件不能实现全部布局功能,因此部分View 层内容需交付给Activity 文件完成。Activity 文件随着页面和业务逻辑的不断增加也会不断增大,代码间耦合度明显提高[1-3],将对项目的升级和维护带来障碍。 因此,对于大中型项目来说,MVC 架构并不可取。

对于一个常规项目,其网络请求必不可少,虽然官方提供了诸如HttpURLConnection 类等HTTP 请求方式,但该类在大量网络请求时,其性能较差。

针对此问题,MVP(Model-View-Presenter)+Retrofit+OkHttp+RxJava 的架构应运而生,该架构能有效降低代码耦合度,使Activity 文件的内容更加单一,网络请求和布局更新更加高效。 对于整个项目而言,整体结构更加清晰,代码可维护性也得到大幅度提升。

本文通过对MVP+Retrofit+OkHttp+RxJava 的研究分析,以《长光卫星云极视》项目的登录模块为应用案例,设计并验证Android 应用开发中MVP 模式和Retrofit2+OkHttp3+RxJava2 的响应式网络请求框架结合的方法及可行性。

1 MVP 模式

1.1 设计思想

MVP 最早出现在IBM 公司的项目研发中,由Model 层(负责数据修改和操作的部分)、View 层(包含所有的UI组件,并负责与Presenter 层进行所有交互操作)、Presenter层(负责所有项目的逻辑)组成[4-5]。

MVP 模式在多名开发人员协同开发及测试时体现出了更大的解耦性。 使用MVP 模式的优势包括:

(1)能将Activity/Fragment 中的任务独立出来;

(2)能将单个复杂的多任务分割成多个简单的任务;

(3)可以分离页面与数据;

(4)促进自动化单元测试[6]。

1.2 实现过程

应用程序中MVP 模式的顺序图如图1 所示。 在一个常规的Android 应用中会有两个参与者:用户(使用该程序的人)和数据(存储的信息实体),以登录操作为例:

(1)用户点击按钮获取验证码;

(2)View 对象接收到用户动作,并向Presenter 层发送委派动作,即执行actionSendMessage()函数;

(3)如果Presenter 层需要接口或数据库中的数据,则会向Model 层通过getMessage()函数发送一条检索数据的消息,在这个过程中,Presenter 层与Model 层属于观察者与被观察者的关系;

(4)当Model 层获取到数据时,Presenter 层将观察到Model 层发送的事件,同时执行returnSendMessage()函数,向View 层发送一条消息,并将获得的验证码返回给用户,至此完成获取验证码的一次操作。

图1 MVP 模式的顺序图

2 响应式网络请求框架

2.1 设计思想

Retrofit2+OkHttp3+RxJava2 是当下最流行的Android网络请求框架之一。 在Android6.0 之前,官方推荐用HttpClient 接口来进行网络请求,后续则更改为Java.net下的HttpUrlConnection 接口,但该方式仅支持HTTP/1.0和HTTP/1.1,不支持HTTP/2.0,也不支持多路复用。 当遇到大量网络请求时性能较差。 与HttpUrlConnection 相比,OkHttp3 底层基于Okio 开源库,使用了比阻塞式IO效率更高的Java NIO(Non-Blocking I/O)。 Retrofit2 作为基于OkHttp 封装的RESTful 网络请求框架, 是当前耦合度最低、功能最强大的网络请求框架。 Retrofit2 与RxJava2结合使用时,前者把请求封装进Observable 对象,在新线程中执行HTTP 请求,请求结束后切换到IO 线程中执行用户的后续动作。总体来说,Retrofit2 用接口的方式进行HTTP 网络请求,并负责请求数据以及接收返回结果,OkHttp3 负责HTTP 请求的过程,RxJava2 负责异步以及多线程的切换。

2.2 OkHttp3

OkHttp 是Square 公司的一款开源的网络请求库,使用OkHttp3 进行网络请求能提高HTTP 请求的加载速度,同时更节省带宽。 OkHttp3 的高效性体现在以下三方面:

(1)允许连接同一主机的所有请求分享同一个socket;

(2)通过响应式缓存来避免重复请求;

(3)当服务端存在多个IP 地址时,若第一个地址连接失败,OkHttp3 会通过尝试备用IP 地址进行静默恢复[7]。

2.3 Retrofit2

与OkHttp 相 同,Retrofit 也 出 自Square 公 司,Retrofit2可以理解为一个HTTP 网络请求的适配器,它将一个HTTP请求通过Java/Kotlin 接口动态代理的方式来表达,并通过OkHttp3 发送HTTP 请求。 Retrofit 和OkHttp 的关系可以总结为:OkHttp 纯粹是一个HTTP/SPDY 客户端;Retrofit 是基于HTTP 的高级REST 抽象。

Retrofit 框架的优势在于:

(1)使用清晰的注解方式,在最大程度上简化URL的拼写形式;

(2)自由度大,支持自定义Converters 及其他业务逻辑;

(3)同时支持同步执行和异步执行;

(4)支持多种文件解析,如GSON、JSON 和XML 等;

(5)支持RxJava。

2.4 RxJava2

RxJava2 是一个在JAVA 虚拟机上使用可观测的序列组成的基于事件的异步程序库。它可以理解为是一种观察者模式,用观察者和被观察者来实现异步操作。 与Android 官方的异步操作方法相比,RxJava 的优势是简洁,当项目随着迭代变得繁琐时,RxJava 仍保持了其简洁性[8]。

2.5 实现过程

基于Retrofit2+OkHttp3+RxJava2 的响应式网络请求框架整体流程如图2 所示。

图2 网络请求流程图

(1)导入相关的依赖,将域名传入一个Retrofit 构造器中;

(2)通过Retrofit.create()方法传入Java 接口并返回一个Call 对象 (该对象默认使用OkHttp3 作为HTTP 请求的Client);

(3)RxJava2 在订阅时调用Call.enqueue()方法来进行HTTP 的异步请求;

(4)在网络请求获得响应后,Call 对象对返回的信息根据设置的转置模式进行转换;

(5)返回结果数据。

3 MVP 模式和网络框架在Android 应用开发中的应用

《长光卫星云极视》项目采取了MVP 模式以及响应式网络框架,以获取登录验证码为例,实现的目录结构如图3 所示。

3.1 Model 层

Model 层主要的功能是从服务端获取数据, 由LoginRepository、LoginService 和 LoginServiceimpl 组成。

(1)LoginRepository

获取用户验证码是通过LoginRepository 类中的send-Message()方法来实现的,通过调用Retrofit2 的send-Message()的方法,实现HTTP 请求,在请求成功后,数据格式转置为SendMessageBean 实体类对象返回,关键代码如下:

图3 项目目录结构图

3.2 View 层

View 层主要对应登录界面LoginFragment,同时View层定义了LoginView 接口,接口中包括获取短信成功及失败的回调方法,LoginPresenter 通过接口returnSendMessage()和returnSendMessageError()方法与LoginFragment 进行交互,关键代码如下:

3.3 Presenter 层

Presenter 层是View 层调用Model 层的桥梁,Login-Presenter 持有LoginView 的引用,在方法中通过用户在LoginFragment 中触发按键时,调用LoginPresenter 的对应方法, 通过LoginService 对象进行对Model 层的访问,同时获取HTTP 返回值的观察者对象,并将值传递给LoginView 对 象,在LoginFragment 中 进 行UI 更 新。 关 键代码如下:

3.4 注意事项

为了快速开发和提高代码质量, 在使用MVP+Retrofit2+OkHttp3+RxJava2 模式时,应采取JUnit 单元测试的方式,对单个Presenter 文件和Service 文件编译运行。 该方式无需在真机或模拟器上全局调试,同时也无需考虑其他类文件的影响。通过JUnit 单元测试,可以快速定位到问题。

4 结论

本文中通过对MVC 模式以及HTTP 网络请求进行系统的分析,发现在一个中大型项目中,采用MVC 模式,会使得充当Controller 层的Activity/Fragment 同时充当View 层的角色,使得文件代码量臃肿,增加了业务逻辑的耦合度,在项目开发上乃至后期维护上都造成了很大的问题。 与此同时,当项目进行复杂多次的网络请求场景时,官方提供的HttpURLConnection 类表现出了性能低下、逻辑复杂的缺陷。

根据MVP 模式的设计思想,将业务事件交付给Presenter 层进行处理,使得Model 层和View 层做到了完全解耦,在整体项目中开发模块职责划分更明显,使逻辑代码的耦合度降低,便于后期的维护和二次开发。 与此同时基于Retrofit+OkHttp+RxJava 的响应式网络框架,在HTTP 请求上更为高效,在业务处理上相比HttpURLConnection 更简化。 RxJava 的使用,会随着网络请求逻辑变得越来越复杂,依然保持简洁。

本文通过上述思想设计并实现了《长光卫星云极视》用户登录模块,验证了MVP 模式与Retrofit+OkHttp+Rx-Java 的网络框架在Android 应用开发中结合的可行性,同时给出了设计思路及关键程序,并最终达到预期效果。

猜你喜欢
观察者耦合度代码
中国北方蒸散-降水耦合度时空变化与水热因子的关系
双速感应电机绕组耦合度研究
辽宁省经济与生态环境耦合协调性分析
冷静而又理性的观察者——德国华人作家刘瑛访谈
创世代码
创世代码
创世代码
创世代码
基于耦合度分析的家禽孵化过程模糊解耦控制系统
观察者模式在Java 事件处理中的应用研究*