5

Android入门第65天-mvvm模式下的retrofit2+okhttp3+rxjava

 2 years ago
source link: https://blog.csdn.net/lifetragedy/article/details/129124746
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Android入门第65天-mvvm模式下的retrofit2+okhttp3+rxjava_retrofit+okhttp+rxjava_TGITCIC的博客-CSDN博客

        一个APP,它所涉及到的内容不只是APP表面这些界面、元素的beautiful和开发。APP之所以为APP它不同于VUE JS、微信小程序,一个APP它内部也分成多个层次,有纯前端、有Adapter、有模型层、有API层、有底层、有缓存、有内嵌存储。

        一个APP其实是一个完整的企业级架构体系,因此APP上才需要架构师,因此APP在业界并没有归到“纯前端”,而叫“大前端”,它是自身独立的一整套体系化知识所组成。

        特别是近几年来,随着智能手机在市场上进一步普及后APP已经不仅仅只是人们以前认知上一个简单的“前端”了。它也已经开始区分出:前端、中间件、缓存、后端、数据库、网络交互、设备交互、动画这些几个主要大科。在这些大科下再衍生出上百个门类的知识点。

        特别是设备交互和网络交互,HTTP/RESULTFUL API交互其实也属于底层。所以作为大前端,架构上非单一层式传统设计时我们经常会进行思考:即我们往往也希望可以像高级语言一样把一些底层features“掩盖”住以加速程序员开发效率。

        因此,今天我们就要讲时下最流行的retrofit2+okhttp3+rxjava封装的http/res㔞 api调用原理。这3个东西组合比较复杂,但是我相信跟着我的教程一步步来绝对保证你一次成功。

为什么不能直接一个OKHTTP3解决而要用3样东西去取待原来一样东西就可以实现的事

        为什么要从“简”变“难”、择“难”去“易”呢?

        当然,这是“码农”的眼光去看待原来一个okhttp3可以搞定的事的角度去思考这件事所能看到的局限。而一旦让我们从全局来看原来所谓“一个okhttp3”可以搞定的事到底是个什么样的情况呢?

        假设,我们有一个get请求,返回是一个{"code":0, "data":"4e23h100hm5ffg8l"}这样的一restful api,我们用okhttp3是怎么实现的呢?

  1. 先要定义http请求头;

  1. 设置一堆的请求变量;

  1. 声明okhttp builder为同步还是异步;

  1. 覆盖on success, on fail等方法;

  1. 判断http返回值是否200;

  1. 如果是200,取body;

  1. body取到后转成gson;

  1. 然后。。。

  1. 然后。。。

  1. 还有异步线程handler回调;

  1. 刷新界面;

        每一个不同的API请求都是上面这一陀。。。对不?然后有人说了。。。你封装呀,把一些重复步骤封装呀。。。哈哈哈。

        说到点了,retrofit+okhttp3+rxjava就是这个封装,当然它不可能封装到开发、程序员们只需要一句话就能实现上面所有步骤,这是不现实的。

        但是retrofit+okhttp3+rxjava可以把以上一堆步骤中的重复书写代码进行了最大程度的封装。。。so。。。已经有“大牛”给你封装了”,你自己也就不用去造轮子了。这就是我在另一个架构系列-高性能零售架构系列里提到的:当团队超过几十人且属于规模化基于一个产品进行协同作战模式下,根本不需要去做什么封装。因为你是对企业的稳定性、性能负责而不是快点交了可以收合同尾款这种乙方性质作法时,你会诞生一种这样的想法:希望这个东西应封装尽封装,不该封装的就不要封,在解决问题、共享信息、消除黑盒、解放生产力、质量、性能上达到最大的balance。这是一种“企业级架构思想”。

        retrofit+okhttp3+rxjava正是这么一种存在,这也是它存在的意义所在即:给予你充分自由又可最大限度消除一些重复代码,并且还掩盖了底层协议部分内容充分解放了程序员的生产力。

        看看似乎有三样东西一起做,其实使用上你是无感的。

        笔者基于这3个组合上,做了少许的小封装,使得它几乎可以适用于任何的开发团队,同时在笔者自己的mao-sir.com上也是使用得是这一套东西,框架代码完全公开给大家。

        下面就让我们一起进入retrofit+okhttp3+rxjava的框架搭建教程。

搭建retrofit2+okhttp3+rxjava

2721abf80a8ff9103defc0a1b72d99f3.png

        以上就是mao-sir的retrofit2+okhttp3+rxjava的框架的结构。

        任何一个业务模块里只要写一个xxx.xxx.api.业务名API就可以使用restful api的访问了。

        看看挺多,其实一点没什么难度,我们一块块把它们“掰开揉碎”了一点点来消化即可。

引入retrofit2+okhttp3+rxjava第三方包

        在模块的build.gradle里引入下面这些包

        引入后它长这样

1a08415313beb4afaf6160563caa7f89.png

http协议层相关类封装

f379e04cffdd0f78767b58c22ccb1346.png

ExceptionHandle.java



newCodeMoreWhite.png

HttpErrorHandler.java



newCodeMoreWhite.png

RequestInterceptor.java



newCodeMoreWhite.png

ResponseInterceptor.java



newCodeMoreWhite.png

        上面协议层可以自己把有需要的http error继续加入进去。上述两个类的作用就是减少了你项目里在restful api调用时那些出错啦、错误码啦怎么处理的一个统一封装,类似我们在spring boot书写时有一个统一的controller层处理抛出exception的AOP机制一样的原理。

拦截http请求、返回报文并输出日志用工具类

        这个类属于辅助类,因为当有了retrofit2+okhttp3+rxjava后,你在你的代码里是看不到类似request过去、get/put/post、response回来这些细节了,那么retrofit2只是对okhttp3的一层包装,我们还是希望看到封装过的restful http请求过时是什么报文、返回时是什么报文这些原始数据以便于调试,因此我们就需要做一个日志工具类来打印和记录这些信息,它好比restful client调试http restful请求时当一条请求发送后,工具的右下角会出现一条:curl语句是一样的作用和目的。

5515aec9299033e5aa28c04baf1f2bce.png

KLog.java



newCodeMoreWhite.png

        它里面还用到了一个辅助类,DataUtil类,代码也附上。

DataUtil.java



newCodeMoreWhite.png

rxjava封装response成object

        rxjava采用的是Observer模式,它可以让你的http请求体在返回时采用异步懒加载的方式,从而不影响到Android的主进程而引起相应的Android崩溃、闪退等问题。

        在retrofit+okhttp+rxjava框架里,三者的分工其实是这样的:

  • Retrofit做上层网络请求接口的封装,同时将需要的数据解析成实体;

  • OkHttp负责请求的过程;

  • RxJava负责异步和线程切换;

a1229f73f255e80353c53132f7a299b4.png

BaseResponse.java



newCodeMoreWhite.png

BaseObserver.java



newCodeMoreWhite.png

        此处请一定记得这个Observer要使用io.reactivex下的Observer。

使用retrofit对于okhttp3的网络请求的封装

5810b89fc52c7191fb0ca79006a7ebc7.png

INetworkRequiredInfo.java



newCodeMoreWhite.png

NetworkRequiredInfo.java

        它是INetworkRequiredInfo的实现类。



newCodeMoreWhite.png

NetworkApi.java

        好了,此处进入主题了。

        介个类,是我们在发起http restful请求的核心类,一般我们在代码里会通过以下这样的调用来完成okhttp3请求的发送:

LoginAPI loginAPI = NetworkApi.createService(LoginAPI.class);

        下面来看NetworkAPI的代码



newCodeMoreWhite.png

        各位可以看到,到这个类为止,retrofit、okhttp3、rxjava全部窜起来用了。

        下面这一句可以明显看到retrofit对okhttp3是如何封装的

        下面我们就要来讲一下,这套封装在实际项目中应该怎么使用了。

在真实案例中使用retrofit2+okhttp3+rxjava

        说,有这么一个需求:我要在每个“需要是否登录校验的界面打开时校验用户是否登录,用户是否登录是通过用户的http请求头-header是否带有ut字段,且这个ut字段在后台是否存在且有效来判断的”。

        因此,后台会提供一个post请求给到前台,如下:

        所以,我们在我们的业务模块里就定义一个API,如:LoginAPI,代码如下:



newCodeMoreWhite.png

        我这边的例子里有post、有get、有header,对于retrofit来说一切只是“方法中的参数”,唯一的区别是annotation的不同。方便吧!

        然后我们来看如何使用retrofit+okhttp3+rxjava来调用和处理一个http请求的返回吧。

实际调用例子

        由于这是一个异步的过程,因此我们不能直接在onSuccess和onFailure里做Android里的界面操作,因为是异步请求和返回的,所以你用代码语句的顺序不代表实际网络请求值到达的时序,因此,我们这边使用了一个小技巧。

        先定义了一个LoginCheckCallBack的接口

LoginCheckCallBack.java

把它跟着调用的上游,传入调用retrofit+okhttp3+rxjava



newCodeMoreWhite.png

        好,接着我们来看isLogin方法



newCodeMoreWhite.png

        这个案例运行后在控制台会产生以下日志,通过日志我们可以清晰的看到okhttp3请求报文和响应的全过程。

把报文请求post出去

a5a1015e1e2f442a2558f7c3e50163bf.png

得到刚才请求的返回

72359b7cae43ca5c22327d9dedbb546a.png

好了,到此结束今天的教程。

        这篇教程就是为下一篇做的前置铺垫,因为在下一篇里我们要使用这个isLogin方法来演示Android里如何使用AOP来对那些需要判定是否登录的界面做统一拦截。

        最后还是那句话,自己不妨动动手试一下吧。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK