热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

RxHttp:新一代Android网络请求神器,一条链发送各种请求

本文由不怕天黑授权投稿原文链接:https:juejin.impost5cbd267fe51d456e2b15f623简介RxHttp是基于OkHttp的二次封装&#

本文由 不怕天黑 授权投稿
原文链接:https://juejin.im/post/5cbd267fe51d456e2b15f623

简介

RxHttp是基于OkHttp的二次封装,并于RxJava做到无缝衔接,一条链就能发送一个完整的请求。主要功能如下:

gradle依赖

implementation 'com.rxjava.rxhttp:rxhttp:1.0.5'//注解处理器,生成RxHttp类,即可一条链发送请求annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.5'//管理RxJava及生命周期,Activity/Fragment 销毁,自动关闭未完成的请求implementation 'com.rxjava.rxlife:rxlife:1.0.5'
//注解处理器,生成RxHttp类,即可一条链发送请求
annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.5'
//管理RxJava及生命周期,Activity/Fragment 销毁,自动关闭未完成的请求
implementation 'com.rxjava.rxlife:rxlife:1.0.5'

项目地址
https://github.com/liujingxing/RxHttp

初始化

//设置debug模式,此模式下有日志打印HttpSender.setDebug(boolean debug)//非必须,只能初始化一次,第二次将抛出异常HttpSender.init(OkHttpClient okHttpClient)//或者,调试模式下会有日志输出HttpSender.init(OkHttpClient okHttpClient, boolean debug)
HttpSender.setDebug(boolean debug)
//非必须,只能初始化一次,第二次将抛出异常
HttpSender.init(OkHttpClient okHttpClient)
//或者,调试模式下会有日志输出
HttpSender.init(OkHttpClient okHttpClient, boolean debug)

此步骤是非必须的,不初始化或者传入null即代表使用默认OkHttpClient对象。

疑问:标题不是说好的是RxHttp,这么用HttpSender做一些初始化呢?这里先卖一个关子,后面会解答

添加公共参数/头部及重新设置url

相信大多数开发者在开发中,都遇到要为Http请求添加公共参数/请求头,甚至要为不同类型的请求添加不同的公共参数/请求头,为此,RxHttp为大家提供了一个静态接口回调,如下,每发起一次请求,此接口就会被回调一次,并且此回调在子线程进行(在请求执行线程回调)

HttpSender.setOnParamAssembly(new Function() {    @Override    public 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"); //添加公共请求头    }});
    @Override
    public 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对象修饰,即是否添加公共参数,默认为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 -> {           //失败回调        });
        .add("key""value");
Disposable disposable = HttpSender.from(param)
        .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
           //成功回调
        }, throwable -> {
           //失败回调
        });

疑问:说好的一条链发送请求呢?别着急,还没到放大招的时候

到这,我可以告诉大家,Param承担的是一个请求体的一个角色,我们通过Param可以确定请求方式(如:Get、Post、Put、Delete等请求方式)、添加请求参数、添加请求头、添加File对象等;然后通过HttpSender,传入Param对象,将请求发送出去。

HttpSender

到这,有人又有疑问,前面初始化、设置公共参数都用到了HttpSender,这里发送请求又用到了HttpSender ,那么它又是承担怎么样的一个角色呢?看名字,我们可以理解为它就是一个请求发送者,通过一个from操作符,传入一个Param对象,然后返回一个RxJavaObservable对象,此时,我们就可以使用RxJava强大的操作符去处理相关的逻辑(这就是简介说的,做到了与RxJava的无缝链接),在这,我们只是使用了subscribe操作符去订阅观察者。

RxHttp

现在,我们正式放大招,标题说好的一条链发送请求,既然吹牛了,就要去实现它。拿上面的例子,看看我们如何一条链实现,上代码

  RxHttp.get("http://...")        .add("key", "value")        .from()          .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果           //成功回调        }, throwable -> {           //失败回调        });
        .add("key""value")
        .from()  
        .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
           //成功回调
        }, throwable -> {
           //失败回调
        });

我们的主角RxHttp终于登场了,可以看到使用RxHttp类我们就实现了一条链完成请求的发送,那它又是承担一个什么角色呢?我们暂时可以理解为RxHttp=Param+HttpSender,并且还有自己特殊的使命。至于什么使用,后面会讲解。

我们现在来解疑惑,为什么我们的库叫RxHttp,但是初始化、设置公共参数等却用HttpSender?因为RxHttp这个类不在RxHttp库中,它是通过注解处理器生成的类。前面我们看到gradle依赖时,使用了

annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.5'

该注解处理器的目的就是在项目中生成RxHttp类,那为何不直接把它写到库里面去呢?前面讲过,因为它有自己的使命,而这个使命,就是我们可以通过注解,在RxHttp中生成自定义的api,我们来看看如何使用注解。

动态设置baseUrl

现实开发中,大部人开发者都会将baseUrl 单独抽取出来,RxHttp也考虑到了这一点,RxHttp通过@DefaultDomain注解来配置baseUrl,看代码

public class Url {    @DefaultDomain() //设置为默认域名    public static String baseUrl = "http://ip.taobao.com/";}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 -> {           //失败回调        });
        .add("key""value")
        .from()  
        .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
           //成功回调
        }, throwable -> {
           //失败回调
        });

RxHttp在发送请求前,会对url做判断,如果没有域名,就会自定加上默认的域名,也就是baseUrl。然后,如果我们不想使用默认的域名呢?RxHttp也考虑到来,提供了一个@Domain注解,我们再来看看用法:

public class Url {    @Domain(name = "Update9158") //设置非默认域名,name 可不传,不传默认为变量的名称    public static String update = "http://update.9158.com";    @DefaultDomain() //设置为默认域名    public static String baseUrl = "http://ip.taobao.com/";}class Url {
    @Domain(name = "Update9158"//设置非默认域名,name 可不传,不传默认为变量的名称
    public static String update = "http://update.9158.com";

    @DefaultDomain() //设置为默认域名
    public static String baseUrl = "http://ip.taobao.com/";
}

此时再rebuild一下项目,就会在RxHttp类中生成一个setDomainToUpdate9158IfAbsent()方法,其中的Update9158字符就是name指定的名字,然后发请求就可以这样:

  RxHttp.get("/service/getIpInfo.php")        .setDomainToUpdate9158IfAbsent()        .add("key", "value")        .from()          .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果           //成功回调        }, throwable -> {           //失败回调        });
        .setDomainToUpdate9158IfAbsent()
        .add("key""value")
        .from()  
        .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
           //成功回调
        }, throwable -> {
           //失败回调
        });

此时,RxHttp检测到url已经配置了域名,就不会再去使用默认的域名。同样的,setDomainToUpdate9158IfAbsent也会检测url 有没有配置域名,如果配置了,也不会使用我们指定的域名。

注意:@Domain注解可以在多个地方使用,而@DefaultDomain()只能在一个地方使用,否则编译不通过,很好理解,默认域名只可能有一个。两个注解都要使用在public static修饰的String类型变量上,对final关键字没有要求,可写可不写,这就表明,baseUrl 可以动态更改,RxHttp始终会拿到的最新的baseUrl 。怎么样,是不是很nice!

更多注解使用请查看:https://juejin.im/post/5cc484146fb9a032332b35ae

接下来,我们来看看,如何发送Post请求、如何在Activity/Fragment销毁时,自动关闭为完成的请求、如何上传/下载文件及进度的监听、如何把Http返回的结果自动解析成我们想要的对象。

注:以下讲解均使用RxHttp

Post

  RxHttp.postForm("http://...")        .add("key", "value")        .from()          .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果           //成功回调        }, throwable -> {           //失败回调        });
        .add("key""value")
        .from()  
        .subscribe(s -> { //这里的s为String类型,即Http请求的返回结果
           //成功回调
        }, throwable -> {
           //失败回调
        });

可以看到,跟上面的Get请求只有一点不同,Get是RxHttp.get,而Post是RxHttp.postForm,除此之外,没有任何区别,我们在看来来,RxHttp都有哪些静态方法供我们选择请求方式

640?wx_fmt=png
可以看到,默认提供了10个静态方法供我们选择具体的请求方式,有Get、Post、Put等,而Post等又分为postForm和postJson,这个好理解,前者是发送表单形式的post请求,后者是发送json字符串的post请求。

现实中,这些默认的请求方式显然不能满足我们的需求,如:我要发送加密的post请求,这个时候该怎么办呢?此时就需要我们自定义请求方式。自定义请求方式请查看RxHttp 一条链发送请求之强大的Param类(三)

Activity 销毁,自动关闭未完成的请求

上面的案例中,在Activity/Fragment销毁时,如果请求还未完成,就会造成Activity/Fragment 无法回收,导致内存泄漏。这是非常严重的问题,那么RxHttp是如何解决的呢?此时,就要引入我自己写的另一个库RxLife,直接看看如何使用

  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 -> {           //失败回调        });
        .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 -> {
           //失败回调
        });

这里的thisLifecycleOwner对象,它是一个接口,这里我们传入的是Activity,因为Activity实现了LifecycleOwner接口。当Activity/Fragment销毁时,会将RxJava的管道中断,管道中断时,又会将未完成的请求自动关闭。

RxLife不了解的同学请查看Android RxLife 一款轻量级别的RxJava生命周期管理库 (一),这里不详细讲解。在下面的讲解中,我们均会使用RxLife

文件上传/下载及进度监听

使用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 -> {            //失败回调        });//发送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 -> {            //下载失败        });
  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-100            long 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 -> {            //下载失败,处理相关逻辑        });
  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-100
            long 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 -> {
            //下载失败,处理相关逻辑
        });

下载进度的监听我们稍微看一下 ,首先一点,下载使用download操作符,而下载进度监听使用downloadProgress操作符,随后,我们使用了doOnNext操作符处理进度回调,注意这里是仅当有进度更新时,才会回调,其中的progress变量是一个Progress类型的对象,我们贴上源码:

public class Progress {    private int  progress; //当前进度 0-100    private long currentSize;//当前已完成的字节大小    private long totalSize; //总字节大小    private T mResult; //http返回结果,上传/下载完成时调用    //省略get/set方法}class Progress<T{
    private int  progress; //当前进度 0-100
    private long currentSize;//当前已完成的字节大小
    private long totalSize; //总字节大小
    private T mResult; //http返回结果,上传/下载完成时调用
    //省略get/set方法
}

由于进度回调会执行101次(上面注释有解释)&#xff0c;而最下面观察者其实是不需要关心这么多事件的&#xff0c;只需要关心最后下载完成的事件&#xff0c;所以使用了filter操作符过滤事件&#xff0c;只要还未下载完成&#xff0c;就将事件过滤调&#xff0c;不让往下走。最终下载完成后&#xff0c;拿到本地下载路径。

文件上传进度监听

  RxHttp.postForm("http://www.......") //发送Form表单形式的Post请求        .add("file1", new File("xxx/1.png"))        .add("file2", new File("xxx/2.png"))        .add("key1", "value1")//添加参数&#xff0c;非必须        .add("key2", "value2")//添加参数&#xff0c;非必须        .addHeader("versionCode", "100") //添加请求头,非必须        .uploadProgress() //注:如果需要监听上传进度&#xff0c;使用uploadProgress操作符        .observeOn(AndroidSchedulers.mainThread()) //主线程回调        .doOnNext(progress -> {            //上传进度回调,0-100&#xff0c;仅在进度有更新时才会回调,最多回调101次&#xff0c;最后一次回调Http执行结果            int currentProgress &#61; progress.getProgress(); //当前进度 0-100            long currentSize &#61; progress.getCurrentSize(); //当前已上传的字节大小            long totalSize &#61; progress.getTotalSize();     //要上传的总字节大小            String result &#61; progress.getResult(); //Http执行结果&#xff0c;最后一次回调才有内容        })        .filter(Progress::isCompleted)//过滤事件&#xff0c;上传完成&#xff0c;才继续往下走        .map(Progress::getResult) //到这&#xff0c;说明上传完成&#xff0c;拿到Http返回结果并继续往下走        .as(RxLife.as(this))  //感知生命周期        .subscribe(s -> { //s为String类型&#xff0c;由SimpleParser类里面的泛型决定的            //上传成功&#xff0c;处理相关逻辑        }, throwable -> {            //上传失败&#xff0c;处理相关逻辑        });//发送Form表单形式的Post请求
        .add("file1"new File("xxx/1.png"))
        .add("file2"new File("xxx/2.png"))
        .add("key1""value1")//添加参数&#xff0c;非必须
        .add("key2""value2")//添加参数&#xff0c;非必须
        .addHeader("versionCode""100"//添加请求头,非必须
        .uploadProgress() //注:如果需要监听上传进度&#xff0c;使用uploadProgress操作符
        .observeOn(AndroidSchedulers.mainThread()) //主线程回调
        .doOnNext(progress -> {
            //上传进度回调,0-100&#xff0c;仅在进度有更新时才会回调,最多回调101次&#xff0c;最后一次回调Http执行结果
            int currentProgress &#61; progress.getProgress(); //当前进度 0-100
            long currentSize &#61; progress.getCurrentSize(); //当前已上传的字节大小
            long totalSize &#61; progress.getTotalSize();     //要上传的总字节大小
            String result &#61; progress.getResult(); //Http执行结果&#xff0c;最后一次回调才有内容
        })
        .filter(Progress::isCompleted)//过滤事件&#xff0c;上传完成&#xff0c;才继续往下走
        .map(Progress::getResult) //到这&#xff0c;说明上传完成&#xff0c;拿到Http返回结果并继续往下走
        .as(RxLife.as(this))  //感知生命周期
        .subscribe(s -> { //s为String类型&#xff0c;由SimpleParser类里面的泛型决定的
            //上传成功&#xff0c;处理相关逻辑
        }, throwable -> {
            //上传失败&#xff0c;处理相关逻辑
        });

上传进度监听使用downloadProgress操作符&#xff0c;剩下的操作跟下载进度监听的操作都一样&#xff0c;通过doOnNext监听上传进度&#xff0c;然后过滤事件&#xff0c;最终拿到Http的返回结果。

数据解析器Parser

在上面的案例中&#xff0c;观察者拿到数据类型都是String类型&#xff0c;然后现实开发中&#xff0c;我们经常需要对数据解析成我们想要的对象&#xff0c;RxHttp考虑到了这一点&#xff0c;现在我们就来看看如何的到我们想要的对象

我们拿淘宝获取IP的接口作为测试接口http://ip.taobao.com/service/getIpInfo.php?ip&#61;63.223.108.42
对应的数据结构如下

public class Response {    private int     code;    private Address data;    //省略set、get方法    class Address {        //为简单起见&#xff0c;省略了部分字段        private String country; //国家        private String region; //地区        private String city; //城市        //省略set、get方法    }}class Response {
    private int     code;
    private Address data;
    //省略set、get方法

    class Address {
        //为简单起见&#xff0c;省略了部分字段
        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 对象        .as(RxLife.asOnMain(this))  //感知生命周期&#xff0c;并在主线程回调        .subscribe(response -> {            //成功回调        }, throwable -> {            //失败回调        });//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 对象
        .as(RxLife.asOnMain(this))  //感知生命周期&#xff0c;并在主线程回调
        .subscribe(response -> {
            //成功回调
        }, throwable -> {
            //失败回调
        });

可以看到&#xff0c;这里我们没有用from操作符&#xff0c;而是用了fromSimpleParser操作符&#xff0c;并且传入Response.class&#xff0c;最后观察者拿到的response变量就是Response类型的对象。怎么样&#xff0c;是不是很简单。RxHttp为我们提供了一系列的fromXXX方法&#xff0c;我们来看一下:

640?wx_fmt&#61;png

我们可以看到&#xff0c;一些基本类型的封装对象RxHttp都为我们封装好了&#xff0c;还有一个fromListParser方法&#xff0c;此方法是用来解析集合对象的&#xff0c;一些常见的数据结构&#xff0c;RxHttp都为我们考虑到了&#xff0c;并封装好了&#xff0c;然后&#xff0c;一些不常见的数据呢&#xff1f;眼尖的你也许发现了&#xff0c;上图中还有一个 Observable from(Parser parser)方法&#xff0c;它允许我们传入一个自定义的解析器&#xff0c;更多解析器的介绍&#xff0c;请查看RxHttp 之强大的数据解析功能&#xff08;二&#xff09;

最后&#xff0c;附上RxHttp一些常用的用法&#xff0c;如下&#xff1a;

  RxHttp.postForm("/service/getIpInfo.php")       //发送Form表单形式的Post请求        .setDomainToUpdate9158IfAbsent()  //手动设置域名&#xff0c;此方法是通过&#64;Domain注解生成的        .tag("RxHttp.get")          //为单个请求设置tag        .setUrl("http://...")       //重新设置url        .setAssemblyEnabled(false)  //设置是否添加公共参数&#xff0c;默认为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 对象  fromXXX都是异步操作符        //感知生命周期&#xff0c;并在主线程回调&#xff0c;当Activity/Fragment销毁时&#xff0c;自动关闭未完成的请求        .as(RxLife.asOnMain(this))          .subscribe(s -> {    //订阅观察者            //成功回调        }, throwable -> {            //失败回调        });//发送Form表单形式的Post请求
        .setDomainToUpdate9158IfAbsent()  //手动设置域名&#xff0c;此方法是通过&#64;Domain注解生成的
        .tag("RxHttp.get")          //为单个请求设置tag
        .setUrl("http://...")       //重新设置url
        .setAssemblyEnabled(false)  //设置是否添加公共参数&#xff0c;默认为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 对象  fromXXX都是异步操作符
        //感知生命周期&#xff0c;并在主线程回调&#xff0c;当Activity/Fragment销毁时&#xff0c;自动关闭未完成的请求
        .as(RxLife.asOnMain(this))  
        .subscribe(s -> {    //订阅观察者
            //成功回调
        }, throwable -> {
            //失败回调
        });

小结

到这&#xff0c;RxHttp的基本用法我们就讲解完毕了&#xff0c;可以看到&#xff0c;使用RxHttp类一条链就能完成一个完整的Http请求&#xff0c;简单一点&#xff0c;就是请求三部曲&#xff1a;

以上所有的案例都离不开这3个步骤。最后&#xff0c;你会发现&#xff0c;RxHttp除了提供的一系列强大的功能外&#xff0c;在写法上&#xff0c;不管什么请求&#xff0c;都极其的相似&#xff0c;只要通过RxHttp类&#xff0c;就能一条链&#xff0c;完成所有的请求&#xff0c;极大的降低了学习成本。

注:要想在项目中生成RxHttp类&#xff0c;至少需要使用一次注解类&#xff0c;否则检测不到注解&#xff0c;就无法生成。

如果你觉得RxHttp&#43;RxLife好用&#xff0c;请记得给我star
如果有好的idea&#xff0c;请留言或者联系我。

更过详情请查看RxHttp系列其它文章&#xff1a;

RxHttp 一条链发送请求之强大的数据解析功能&#xff08;二&#xff09;
https://juejin.im/post/5cc095b7f265da0379417be0

RxHttp 一条链发送请求之强大的Param类&#xff08;三&#xff09;
https://juejin.im/post/5cc47e575188252da72219ca

RxHttp 一条链发送请求之注解处理器 Generated API&#xff08;四&#xff09;
https://juejin.im/post/5cc484146fb9a032332b35ae



推荐阅读
探索 Android 平台的 CameraX
Lottie 实现炫酷动画背后的原理



编程·思维·职场
欢迎扫码关注

640?wx_fmt&#61;jpeg


  在看也是一种认可640?wx_fmt&#61;gif


推荐阅读
  • 对okhttp网络请求的简单介绍publicclassAppextendsApplication{OkHttpClient实例是唯一的,所有的请求都会通过 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 标题: ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
  • Retrofit+Rxjava+OkHttp
    为什么80%的码农都做不了架构师?参考:http:duanyytop.github.io20160806Retrofit%E7%94%A8%E6% ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
author-avatar
光明使者之快乐天使_101
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有