okhttp rxjava retrofit教程
RxJava和Retrofit也火了一段时间了,不过最近一直在学习ReactNative和Node相庙堠杼寺关的姿势,一直没有时间研究这些新东西,最近有个项目准备写,打算先用Android写一个Demo出来,却发现Android的世界发生了天翻地覆的变化,EventBus和OKHttp啥的都不见了,RxJava和Retrofit是什么鬼?
基本页面
1、基本页面先扔出build.gradle文件的内容
2、也就是说本文是基于RxJava1.1.0和Retrofit 2.0.0-beta4来进行的。 添加rxandroid是因为rxjava中的线程问题。下面先搭建一个基本的页面,页面很简单,先来看文件目录结构
3、activity_main.xml的代码如下:
4、MainActivity.java的代码如下:
5、注意不要忘记加网络权限:
只用Retrofit
1、我们准备在getMovie方法中进行网络请求,我们先来看看只使用Retrofit是如何进行的。至于返回的数据格式,大家自己访问下链接就看到了,太长就不放进来了。首先我们要根据返回的结果封装一个Entity,暂命名为MovieEntity,代码就不贴了
https://api.douban.com/v2/movie/top250?start=0&count=102、接下来我们要创建一个接口取名为MovieService,代码如下:
3、回到MainActivity之中,我们来写getMovie方法的代码
4、以上为没有经过封装的、原生态的Retrofit写网络请求的代码。 我们可以封港粕登漪装创建Retrofit和service部分的代码,然后Activ足毂忍珩ity用创建一个Callback作为参数给Call,这样Activity中只关注请求的结果,而且Call有cancel方法可以取消一个请求,好像没Rxjava什么事了,我觉得可以写到这就下班了~接下来我们要面对的问题是这样的 如果我的Http返回数据是一个统一的格式,例如
5、我们如何对返回结果进行一个统一的处理呢?另外,我的ProgressDialog的show方法应该在哪调用呢?看样子只能在getMovi髫潋啜缅e()这个方法里面调用了,换个地方发出请求就要在对应的Listener里面写一遍show()的代码,其实挺闹心。而且错误请求我也想集中处理掉不要贴重复的代码。我们先来看结合了Rxjava之后,事情有没有变化的可能。当然即便是不用Rxjava,依旧能够做很多的封装,只是比较麻烦。如需查看项目代码 --> 代码地址: 选择Tag -> step1
https://github.com/tough1985/RxjavaRetrofitDemo添加Rxjava
1、Retrofit本身对Rxjava提供了支持。添加Retrofit对Rxjava的支持需要在Gradle文件中添加
2、当然我们已经添加过了。然后在创建Retrofit的过程中添加如下代码:
3、这样一来我们定义的service返回值就不在是一个Call了,而是一个Observable重新定义MovieService
4、getMovie方法改为:
5、这样基本上就完成了Retrofit和Rxjava的结合,但是我知道你们当然不会满意的。接下来我们把创建Retrofit的过程封装一下,然后希望Activity创建Subscriber对象传进来。如需查看项目代码 --> 代码地址:选择Tag -> step2
https://github.com/tough1985/RxjavaRetrofitDemo将请求过程进行封装
1、创建一个对象HttpMethods
2、用一个单例来封装该对象,在构造方法中创建Retrofit和对应的Service。 如果需要访问不同的基地址,那么你可能需要创建多个Retrofit对象,或者干脆根据不同的基地址封装不同的HttpMethod类。我们回头再来看MainActivity中的getMovie方法:其中subscriber是MainActivity的成员变量。如需查看项目代码 --> 代码地址:选择Tag -> step3
https://github.com/tough1985/RxjavaRetrofitDemo相同格式的Http请求数据该如何封装
1、第二部分和第三部分我参考了知乎上的一个问答:RxJava+Retrofit,在联网返回后如何先进行统一的判断?不过没有完整的示例,所以在这写一个完整的示例出来。这个段落我们来聊一下有些Http服务返回一个固定格式的数据的问题。 例如:
2、大部分的Http服务可能都是这样设置,resultCode和resultMessage的内容相对比较稳定,而data的内容变化多端,72变拎枋辏话都不一定够变的,有可能是个User对象,也有可能是个订单对象,还有可能是个订单列表。 按照我们之前的用法,使用Gson转型需要我们在创建subscriber对象是指定返回值类型,如果我们对不同的返回值进行封装的话,那可能就要有上百个Entity了,看着明明是很清晰的结构,却因为data的不确定性无奈了起来。我们可以创建一个HttpResult类
3、如果data是一个User对象的话。那么在定义Service方法的返回值就可以写为
4、这样一来HttpResult就相当于一个包装类,将结果包装了起来,但是在使用的时候要给出一个明确的类型。在上面的示例中,我也创建了一个HttpResult类,用来模仿这个形式,将其中的Subject单独封装了起来。