App 组件化/模块化之路——如何封装网络请求框架

在 App 开发中网络请求是每个开发者必备的开发库,也出现了许多优秀开源的网络请求库。例如

  • okhttp
  • retrofit
  • android-async-http

这些网络请求库很大程度上提高程序猿的编码效率。但是随着业务的发展,App 变得越来越大,我们将这些网络请求库加入到项目中直接使用,对我们业务类的入侵是非常强的。如果要进行业务分离时,这些网络请求代码将是一个阻止我们进一步工作的绊脚石。对开发者来说是非常痛苦的。

因此我们构建的网络请求框架要可以解决以下问题:

  • 分离业务与网络请求代码
  • 网络库可以很容易的被替换
  • 网络库可以很方便的复用

所以在 App 组件化/模块化开发架构思路 一文中,我们把网络请求作为内核层的一个组件。

封装第三方网络请求接口

一般来说,目前绝大部分 App 的数据请求都是使用 HTTP 协议,而数据交换的协议使用 json 格式。因此可以封装一个通用的请求接口。(当然还有其他一些协议,例如微信的 mars ,但是封装的思路是一致的,本文为了简单说明,暂时使用通用网络请求框架,不排除以后会对 mars 的封装)

首先预览一下框架结构

IRequest

这个类封装了网络请求的通用接口,定义请求接口 doRequest() 、获取请求连接 getUrl() 、获取请求方法 getHttpMethod() 等。

public interface IRequest {enum HttpMethod {GET, POST, PUT, DELETE}//... 为了减少代码的篇幅,省略一些对本文说明不重要的片段,本文代码可以在//https://github.com/wecodexyz/Componentization 获取到void addParams(Map<String, String> params);String getUrl();Pair<Integer, String> doRequest();boolean isSupportCache();void addHeader(String key, String value);HttpMethod getHttpMethod();//... 为了减少代码的篇幅,省略一些对本文说明不重要的片段,本文代码可以在//https://github.com/wecodexyz/Componentization 获取到
}

Request

这个类是个抽象类,对 IRequest 的实现。目前是一个简单封装的实现。

RequestWrapper

这个类是一个泛型类,继承于 Request 并对第三方请求库的封装。例如本文就是对 okhttp 的封装,而泛型 T 对象就是请求得到的具体数据类型。如果要对其他请求库进行封装,就可以参考这个类的实现。

注意这个类封装是纯粹的网络请求,不应该包含业务类相关的代码。否则无解决上文提出的三个问题。

public abstract class RequestWrapper extends Request {//... 为了减少代码的篇幅,省略一些对本文说明不重要的片段,本文代码可以在//https://github.com/wecodexyz/Componentization 获取到
@Overridepublic Pair<Integer, String> doRequest() {Pair<Integer, String> result = new Pair<>(ERROR_NETWORK, "");okhttp3.Request request = null;if (getHttpMethod() == HttpMethod.POST) {request = requestBuilder().url(getUrl()).post(requestBody()).build();} else {request = requestBuilder().url(getUrlWithParams()).build();}try {Response response = mClient.newCall(request).execute();if (response.isSuccessful()) {result = new Pair<>(response.code(), response.body().string());} else {result = new Pair<>(response.code(), response.message());}} catch (IOException e) {Log.e(TAG, e.getMessage());}return result;}//... 为了减少代码的篇幅,省略一些对本文说明不重要的片段,本文代码可以在//https://github.com/wecodexyz/Componentization 获取到
}

关键的代码是在 doRequest() 方法中,该方法实现了网络请求的代码,返回一个 Pair<Integer,String>对象,该对象的 first 属性是一个请求 code ,用于标识网络请求码(即是网络请求返回的200,404,301等)。而 second 就是网络请求的数据。

BaseTextRequest

这个类就是网络请求框架提供给业务类使用的一个接口。本文一开始就提出来 json 作为交互数据请求的协议。那么此类的封装就有利于业务数据的访问。

public abstract class BaseTextRequest<T> extends RequestWrapper {public BaseTextRequest(Context context) {super(context);}public Flowable<T> request() {return Flowable.fromCallable(new Callable<Pair<Integer, String>>() {@Overridepublic Pair<Integer, String> call() throws Exception {Pair<Integer, String> result = doRequest();return result;}}).flatMap(new Function<Pair<Integer, String>, Publisher<T>>() {@Overridepublic Publisher<T> apply(@NonNull Pair<Integer, String> pair) throws Exception {if (isSuccessful(pair.first)) {return Flowable.just(onRequestFinish(pair.second));}return Flowable.just(onRequestError(pair.first, pair.second));}});}@Overridepublic boolean isSupportCache() {return true;}protected abstract T onRequestFinish(String result);protected abstract T onRequestError(int code, String message);
}

由于请求网络是耗时的操作,rxjava2 来实现网络请求异步操作。 request 是对 RequestWrapper.doRequest() 方法的封装,并得到一个 Flowable 对象。同时定义了 onRequestFinish()onRequestError() 两个方法。

这两个方法就是具体业务类要处理的逻辑。

SimpleTextRequest

假设有一个请求业务数据接口,返回数据是一个字符串。那么我们使用我们的框架就是这样来使用。本文例子是请求我们项目中的 README.md 的内容。用起来非常简单,只要继承于 BaseTextRequest,并实现 getUrl()onRequestFinish() onRequestError()getHttpMethod() 这几个方法。

注意严格来说这是一个业务类,所以是不应该放在 core 目录下的。

public class SimpleTextRequest extends BaseTextRequest<String> {public SimpleTextRequest(Context context, Map<String, String> params) {super(context);addParams(params);}@Overridepublic String getUrl() {return "https://raw.githubusercontent.com/wecodexyz/Componentization/master/README.md";}@Overridepublic HttpMethod getHttpMethod() {return HttpMethod.GET;}@Overrideprotected String onRequestFinish(String result) {//这里可以实现对 json 数据的解析,例如使用 JSONObject //对象解析具体的业务return result;}@Overrideprotected String onRequestError(int code, String message) {return message;}
}

测试请求框架

request = new SimpleTextRequest(this, null);request.request().subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {@Overridepublic void accept(@NonNull String s) throws Exception {textView.setText(s);//这里返回接口请求的数据
                    }}, new Consumer<Throwable>() {@Overridepublic void accept(@NonNull Throwable throwable) throws Exception {textView.setText(throwable.getMessage());}});

本文运行的结果

项目地址:https://github.com/wecodexyz/Componentization

微信关注我们,可以获取更多

App 组件化/模块化之路——如何封装网络请求框架相关推荐

  1. Anroid-async-http封装网络请求框架源码分析

    Android-async-http开源项目可以是我们轻松的获取网络数据或者向服务器发送数据,使用起来非常简单, 这个网络请求库是基于Apache HttpClient库之上的一个异步网络请求处理库, ...

  2. 基于OkHttp3封装网络请求框架

    前言 网络请求可以说是开发一款移动APP最核心的基础功能了,通过实际工作中以及浏览了许多网络框架之后,本篇在这里分享慕课一位老师基于OkHttp封装的一个轻量的网络框架,至于为什么说它轻量,因为代码少 ...

  3. Android 基于注解IOC组件化/模块化的架构实践

    当前参与的项目历史也很久远,第一行代码据说是写于2014年的某一天,那时Android用的ide还是Eclipse.那时Android还没有很好的架构指导(mvp.mvvm).那时Android最新的 ...

  4. 得到、微信、美团、爱奇艺APP组件化架构实践

    一.背景 随着项目逐渐扩展,业务功能越来越多,代码量越来越多,开发人员数量也越来越多.此过程中,你是否有过以下烦恼? 项目模块多且复杂,编译一次要5分钟甚至10分钟?太慢不能忍? 改了一行代码 或只调 ...

  5. 大型Android项目架构:基于组件化+模块化+Kotlin+协程+Flow+Retrofit+Jetpack+MVVM架构实现WanAndroid客户端

    前言:苟有恒,何必三更眠五更起:最无益,莫过一日曝十日寒. 前言 之前一直想写个 WanAndroid 项目来巩固自己对 Kotlin+Jetpack+协程 等知识的学习,但是一直没有时间.这里重新行 ...

  6. iOS爱康APP组件化架构

    iOS爱康APP组件化架构 随着公司业务需求的不断增加以及快速产出,要对应用的架构做相关的设计和优化,使可以快速复用扩展.减少耦合.减少开发时间成本.减少测试成本等.基础框架架构就是为解决这些问题所设 ...

  7. Android中网络请求框架的封装-Retrofit+RxJava+OkHttp

    Retrofit注解 请求方法 注解代码 请求格式 @GET GET请求 @POST POST请求 @DELETE DELETE请求 @HEAD HEAD请求 @OPTIONS OPTIONS请求 @ ...

  8. android网络请求框架_2020,最新APP重构:网络请求框架

    在现在的app,网络请求是一个很重要的部分,app中很多部分都有或多或少的网络请求,所以在一个项目重构时,我会选择网络请求框架作为我重构的起点.在这篇文章中我所提出的架构,并不是所谓的 最好 的网络请 ...

  9. 模仿Retrofit封装一个使用更简单的网络请求框架

    本文已授权微信公众号:郭霖  在微信公众号平台原创首发.会用Retrofit了?你也能自己动手写一个! 前言 想封装一套网络请求,不想直接上来就用别人写好的,或者说对项目可以更好的掌控,所以自己模仿着 ...

最新文章

  1. 计算机网络实验二交换机配置Cisco,思科实验1计算机和交换机的ip地址设置
  2. 测试 MySQL 性能的几款工具
  3. qq空间网页版电脑_常用QQ软件,电脑C盘快满了,占用太多空间,如何快速清理?...
  4. 泛泰SKY新出品 DMB电视手机IM-U160
  5. JVM和GC知识点整理
  6. 四:Cocos2d-x设计思想
  7. SQLyog——下载2058问题
  8. 发现了《ACE程序员教程》中一个例程的问题
  9. 漫游书海-我的阅读简史
  10. java属于什么语言_java是什么语言 ?是什么系统?
  11. tkinter制作选择文件夹对话框
  12. 外卖分销分佣小程序外卖cps小程序返利系统源码分享
  13. vb.net word 自定义工具栏_20个Word文字处理快速掌握技巧
  14. ios label内字体置顶_IOS_Vertically align UILabel文本置顶 | 学步园
  15. select 多选下拉框获取值
  16. 【源码】Set集合源码剖析
  17. 学习git的第一节课
  18. 华为云数据库SQL Server 上云最佳实践
  19. 一种基于计算机网络的流媒体,基于网络计算机的流媒体播放器的研究与实现.pdf...
  20. PC端-拖动表格组件

热门文章

  1. 2019年上半年收集到的人工智能自然语言处理方向干货文章
  2. 一篇文章教你搞定传说中的“随机森林”
  3. AI突破难题才能预见未来
  4. 4句话让你明白什么是AI
  5. 复杂科学2021年度精选:从诺贝尔奖到未来科学
  6. 重磅!脑机接口突破登Nature封面,脑中“笔迹”转屏幕文字破纪录,准确率超99%...
  7. 《神经元》发表脑智卓越中心关于灵活分类决策神经环路机制的研究成果
  8. 解析|一文读懂AGV的关键技术——激光SLAM与视觉SLAM的区别
  9. 人类为什么更聪明 | 人脑神经元关键结构差异被揭示
  10. Google Brain与牛津大学主持最新《计算机视觉前沿》报告(146页PPT)