[转]RxHttp 一条链发送请求,新一代Http请求神器(一)
简介
RxHttp是基于OkHttp的二次封装,并于RxJava做到无缝衔接,一条链就能发送一个完整的请求。主要功能如下:
- 支持Get、Post、Put、Delete等任意请求方式,可自定义请求方式
- 支持Json、DOM等任意数据解析方式,可自定义数据解析器
- 支持文件下载/上传,及进度的监听,并且支持断点下载
- 支持在Activity/Fragment的任意生命周期方法,自动关闭未完成的请求
- 支持添加公共参数/头部信息,且可动态更改baseUrl
- 支持请求串行和并行
implementation 'com.rxjava.rxhttp:rxhttp:1.0.4'
//注解处理器,生成RxHttp类,即可一条链发送请求
annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.4'
//管理RxJava及生命周期,Activity/Fragment 销毁,自动关闭未完成的请求
implementation 'com.rxjava.rxlife:rxlife:1.0.4'
初始化
//设置debug模式,此模式下有日志打印
HttpSender.setDebug(boolean debug)
//非必须,只能初始化一次,第二次将抛出异常
HttpSender.init(OkHttpClient okHttpClient)
//或者,调试模式下会有日志输出
HttpSender.init(OkHttpClient okHttpClient, boolean debug)
此步骤是非必须的,不初始化或者传入null
即代表使用默认OkHttpClient对象。
疑问:标题不是说好的是RxHttp,这么用HttpSender做一些初始化呢?这里先卖一个关子,后面会解答
添加公共参数/头部及重新设置url
HttpSender.setOnParamAssembly(new Function() {@Overridepublic Param apply(Param p) { if (p instanceof GetRequest) {//根据不同请求添加不同参数} else if (p instanceof PostRequest) {} else if (p instanceof PutRequest) {} else if (p instanceof DeleteRequest) {}//可以通过 p.getSimpleUrl() 拿到url更改后,重新设置//p.setUrl("");return p.add("versionName", "1.0.0")//添加公共参数.addHeader("deviceType", "android"); //添加公共请求头}
});
然后有些请求我们不希望添加公共参数/请求头,RxHttp又改如何实现呢?很简单,发起请求前,设置不添加公共参数,如下:
Param param = Param.get("http://...")//设置是否对Param对象修饰,即是否添加公共参数,默认为true.setAssemblyEnabled(false); //设为false,就不会回调上面的静态接口
到这,也许你们会有疑问,Param
是什么东东,下面就为大家讲解。
Param
Param param = Param.get("http://...").add("key", "value");
Disposable disposable = HttpSender.from(param).subscribe(s -> { //这里的s为String类型,即Http请求的返回结果//成功回调}, throwable -> {//失败回调});
HttpSender
RxHttp
现在,我们正式放大招,标题说好的一条链发送请求,既然吹牛了,就要去实现它。拿上面的例子,看看我们如何一条链实现,上代码
RxHttp.get("http://...").add("key", "value").from() .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果//成功回调}, throwable -> {//失败回调});
annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.2'
动态设置baseUrl
现实开发中,大部人开发者都会将baseUrl 单独抽取出来,RxHttp也考虑到了这一点,RxHttp通过@DefaultDomain
注解来配置baseUrl,看代码
public class Url {@DefaultDomain() //设置为默认域名public static String baseUrl = "http://ip.taobao.com/";
}
rebuild一下项目,此时我们发送请求就可以直接传入path路径,如下:
RxHttp.get("/service/getIpInfo.php").add("key", "value").from() .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果//成功回调}, throwable -> {//失败回调});
public class Url {@Domain(name = "Update9158") //设置非默认域名,name 可不传,不传默认为变量的名称public static String update = "http://update.9158.com";@DefaultDomain() //设置为默认域名public static String baseUrl = "http://ip.taobao.com/";
}
RxHttp.get("/service/getIpInfo.php").setDomainToUpdate9158IfAbsent().add("key", "value").from() .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果//成功回调}, throwable -> {//失败回调});
接下来,我们来看看,如何发送Post请求、如何在Activity/Fragment销毁时,自动关闭为完成的请求、如何上传/下载文件及进度的监听、如何把Http返回的结果自动解析成我们想要的对象。
Post
RxHttp.postForm("http://...").add("key", "value").from() .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果//成功回调}, throwable -> {//失败回调});
现实中,这些默认的请求方式显然不能满足我们的需求,如:我要发送加密的post请求,这个时候该怎么办呢?此时就需要我们自定义请求方式。自定义请求方式请查看RxHttp 扩展篇之Param扩展(七)
Activity 销毁,自动关闭未完成的请求
RxHttp.postForm("http://...").add("key", "value").from().as(RxLife.as(this)) //订阅观察者前,加上这句话即可.subscribe(s -> {//成功回调}, throwable -> {//失败回调});//或者RxHttp.postForm("http://...").add("key", "value").from().as(RxLife.asOnMain(this)) //asOnMain 可以在主线程回调观察者.subscribe(s -> {//成功回调}, throwable -> {//失败回调});
文件上传/下载及进度监听
使用RxHttp
,可以很优雅的实现文件上传/下载及进度的监听,如何优雅?直接上代码
RxHttp.postForm("http://...") //发送Form表单形式的Post请求.add("key", "value").add("file1", new File("xxx/1.png")) //添加file对象.add("file2", new File("xxx/2.png")).from() //from操作符,是异步操作.as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调.subscribe(s -> { //成功回调}, throwable -> {//失败回调});
可以看到,文件上传跟普通的post请求其实没啥区别,无非就是在post请求的基础上,调用add方法添加要上传的文件对象。
//文件存储路径String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk").download(destPath) //注意这里使用download操作符,并传入本地路径.as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调.subscribe(s -> {//下载成功,回调文件下载路径}, throwable -> {//下载失败});
下载跟普通请求不同的是,下载使用的是download
操作符,其它都一样。
//文件存储路径String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk").downloadProgress(destPath) //注:如果需要监听下载进度,使用downloadProgress操作符.observeOn(AndroidSchedulers.mainThread()).doOnNext(progress -> {//下载进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调文件存储路径int currentProgress = progress.getProgress(); //当前进度 0-100long currentSize = progress.getCurrentSize(); //当前已下载的字节大小long totalSize = progress.getTotalSize(); //要下载的总字节大小String filePath = progress.getResult(); //文件存储路径,最后一次回调才有内容}).filter(Progress::isCompleted)//下载完成,才继续往下走.map(Progress::getResult) //到这,说明下载完成,返回下载目标路径.as(RxLife.as(this)) //感知生命周期.subscribe(s -> {//s为String类型,这里为文件存储路径//下载完成,处理相关逻辑}, throwable -> {//下载失败,处理相关逻辑});
public class Progress<T> {private int progress; //当前进度 0-100private long currentSize;//当前已完成的字节大小private long totalSize; //总字节大小private T mResult; //http返回结果,上传/下载完成时调用//省略get/set方法
}
RxHttp.postForm("http://www.......") //发送Form表单形式的Post请求.add("file1", new File("xxx/1.png")).add("file2", new File("xxx/2.png")).add("key1", "value1")//添加参数,非必须.add("key2", "value2")//添加参数,非必须.addHeader("versionCode", "100") //添加请求头,非必须.uploadProgress() //注:如果需要监听上传进度,使用uploadProgress操作符.observeOn(AndroidSchedulers.mainThread()) //主线程回调.doOnNext(progress -> {//上传进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,最后一次回调Http执行结果int currentProgress = progress.getProgress(); //当前进度 0-100long currentSize = progress.getCurrentSize(); //当前已上传的字节大小long totalSize = progress.getTotalSize(); //要上传的总字节大小String result = progress.getResult(); //Http执行结果,最后一次回调才有内容}).filter(Progress::isCompleted)//过滤事件,上传完成,才继续往下走.map(Progress::getResult) //到这,说明上传完成,拿到Http返回结果并继续往下走.as(RxLife.as(this)) //感知生命周期.subscribe(s -> { //s为String类型,由SimpleParser类里面的泛型决定的//上传成功,处理相关逻辑}, throwable -> {//上传失败,处理相关逻辑});
上传进度监听使用downloadProgress
操作符,剩下的操作跟下载进度监听的操作都一样,通过doOnNext
监听上传进度,然后过滤事件,最终拿到Http的返回结果。
数据解析器Parser
在上面的案例中,观察者拿到数据类型都是String类型,然后现实开发中,我们经常需要对数据解析成我们想要的对象,RxHttp
考虑到了这一点,现在我们就来看看如何的到我们想要的对象
我们拿淘宝获取IP的接口作为测试接口http://ip.taobao.com/service/getIpInfo.php?ip=63.223.108.42
对应的数据结构如下
public class Response {private int code;private Address data;//省略set、get方法class Address {//为简单起见,省略了部分字段private String country; //国家private String region; //地区private String city; //城市//省略set、get方法}
}
RxHttp.get("http://ip.taobao.com/service/getIpInfo.php") //Get请求.add("ip", "63.223.108.42")//添加参数.addHeader("accept", "*/*") //添加请求头.addHeader("connection", "Keep-Alive").addHeader("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)").fromSimpleParser(Response.class) //这里返回Observable<Response> 对象.as(RxLife.asOnMain(this)) //感知生命周期,并在主线程回调.subscribe(response -> {//成功回调}, throwable -> {//失败回调});
RxHttp.postForm("/service/getIpInfo.php") //发送Form表单形式的Post请求.setDomainToUpdate9158IfAbsent() //手动设置域名,此方法是通过@Domain注解生成的.tag("RxHttp.get") //为单个请求设置tag.setUrl("http://...") //重新设置url.setAssemblyEnabled(false) //设置是否添加公共参数,默认为true.cacheControl(CacheControl.FORCE_NETWORK) //缓存控制.setParam(Param.postForm("http://...")) //重新设置一个Param对象.add(new HashMap<>()) //通过Map添加参数.add("int", 1) //添加int类型参数.add("float", 1.28838F) //添加float类型参数.add("double", 1.28838) //添加double类型参数.add("key1", "value1") //添加String类型参数.add("key2", "value2", false) //根据最后的boolean字段判断是否添加参数 .add("file1", new File("xxx/1.png")) //添加文件对象.addHeader("headerKey1", "headerValue1") //添加头部信息.addHeader("headerKey2", "headerValue2", false)//根据最后的boolean字段判断是否添加头部信息 .fromSimpleParser(String.class) //这里返回Observable<T> 对象 fromXXX都是异步操作符//感知生命周期,并在主线程回调,当Activity/Fragment销毁时,自动关闭未完成的请求.as(RxLife.asOnMain(this)) .subscribe(s -> { //订阅观察者//成功回调}, throwable -> {//失败回调});
小结
到这,RxHttp
的基本用法我们就讲解完毕了,可以看到,使用RxHttp
类一条链就能完成一个完整的Http请求,简单一点,就是请求三部曲:
注:
要想在项目中生成RxHttp类,至少需要使用一次注解类,否则检测不到注解,就无法生成。
如果你觉得RxHttp+RxLife好用,请记得给我star
如果有好的idea,请留言或者联系我。
RxHttp 扩展篇之注解处理器 Generated API(七)
[转]RxHttp 一条链发送请求,新一代Http请求神器(一)相关推荐
- RxHttp 一条链发送请求,新一代Http请求神器(一)
简介 RxHttp是基于OkHttp的二次封装,并于RxJava做到无缝衔接,一条链就能发送一个完整的请求.主要功能如下: 支持Get.Post.Put.Delete等任意请求方式,可自定义请求方式 ...
- RxHttp 一条链发送请求之强大的Param类(三)
简介 前面我们对RxHttp做了整体的介绍,我们知道,使用RxHttp库发送请求,有两种方式.一种通过Param+HttpSender的形式,另外一种是直接使用RxHttp类,而RxHttp类内部其实 ...
- RxHttp 一条链发送请求之注解处理器 Generated API(四)
前言 在前面3篇文章中,我们对RxHttp做了整体的介绍,并带领大家自定义Parser及Param,如果还没阅读,请查看 如果还未阅读前面两篇文章,请查看 RxHttp 一条链发送请求,新一代Http ...
- RxHttp 一条链发送请求之强大的数据解析功能(二)
前言 在上一文中,我们对RxHttp做了一个整体的介绍,文章一经发表后,就收到了广大读者众多不同的声音,有对我的肯定,也有对RxHttp提出改进的建议,更有读者直接指出了我的不足,为此,我收获了很多, ...
- RxHttp-一条链发送请求之强大的数据解析功能(二),kotlin构造器
}, throwable -> { //失败回调 }); 可以看到,直接使用fromListParser操作符,传入Student.class即可,它内部就是通过ListParser.get(S ...
- RxHttp 一款让你眼前一亮的 Http 请求框架
本文系 RxHttp作者不怕天黑 向本博客投稿,并授权在本站发表. 1.前言 RxHttp在今年4月份一经推出,就受到了广大Android 开发者的喜爱,截止本文发表在github上已有1100+st ...
- JAVA发送HttpClient请求及接收请求结果过程
1.写一个HttpRequestUtils工具类,包括post请求和get请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ...
- 新闻丨智链万源“新一代产业科技产品体系C4X”晋级第五届“i创杯”复赛
2019年5月19日,由江苏省工业和信息化厅指导,中南谷.创客公社承办,中南资本.米域MIXPACE联合承办的第五届"i创杯"互联网创新创业大赛巡回路演之上海站,在上海米域MIXP ...
- 没有一条链能通吃全世界
你去工行,转账给建行的朋友,填单输密码,完成第一步:支付. 但钱并没有到你朋友账上,此时工行开始第二步:结算--把收款人信息发送建行,把钱交给人民银行(人行). 人行负责第三步:清算--左手收下工行的 ...
最新文章
- NodeJS和C++之间的类型转换
- 淘宝开源Android容器化框架Atlas开发者指南
- 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例 1
- CPU、GPU、FPGA、ASIC等AI芯片特性及对比
- P7581-「RdOI R2」路径权值【长链剖分,dp】
- Java中各种对象的各种实例化方式
- 大数据之-Hadoop3.x_Yarn_常用命令---大数据之hadoop3.x工作笔记0147
- 为什么买入不了创业版_趋势波段买卖创业板ETF指数基金能轻松保险盈利
- 漫画:996 的本质是什么?
- CPU溫度高的9種可能
- [转载] c++的vector赋值方法汇总
- Unity Manual learning log
- fatal: Authentication failed for又不弹出用户名和密码 解决办法
- iphone分屏功能怎么用_除iOS12.4苹果还为旧款设备推送了更新 来看iPhone迁移怎么用...
- 火狐浏览器安装插件“组件未验证无法安装”问题解决
- python xlsxwriter dict_Python玩转Excel神器xlsxwriter详解
- 第二代支付系统专题之报文篇(一)小额支付报文完整版(含二代新增功能业务说明)
- 最新抖音视频无水印解析接口-突破频率限制
- ppt加html链接,ppt制作中如何添加超链接(完整版).doc
- opencv中step、step1、size、elemSize以及elemSize1区别