理想论坛_专业20年的财经股票炒股论坛交流社区 - 股票论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2719|回复: 0

RxHttp 让你眼前一亮的Http请求框架

[复制链接]

9650

主题

9650

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
28966
发表于 2019-12-27 13:53 | 显示全部楼层 |阅读模式
1、前言

RxHttp在今年4月份一经推出,就遭到了广大Android 开辟者的喜好,停止本文颁发在github上已有1100+star,为此,我自己也建个RxHttp&RxLife 的群(群号:378530627)现在群里也有快要180号人,里面有很多小同伴提了很多有价格的创意,才使得RxHttp不停对峙走到了现在,在此,感激大家的喜好。
这时代,不停有人问我,retrofit不香吗?之前不晓得该怎样答复这个题目,现在我想说,香!!retrofit无疑是现在综合得分最高的选手,但它也有它的不够。
RxHttp相较于retrofit,功用上,两者均能实现,并无多大不同,更多的不同表现功用的操纵上,也就是易用性,如对文件上传/下载/进度监听的操纵上,RxHttp用及简的API,可以说碾压retrofit;此外在baseUrl、公共参数/请求头、请求加解密等功用上的易用性都要优于retrofit;但是这些,小我以为都不算什么,小我以为RxHttp最大的上风在于它近乎为0的上手本钱、极简的API以及高扩大性,看完这篇文章,信任你会有同感。
那RxHttp就没有弱点吗?有,那就是它的安定性现在还不如retrofit,究竟RxHttp刚出道8个月,且全数是我一小我在保护,固然,并不是说RxHttp不安定,RxHttp未开源前,在我司的项目已经操纵了近2年,接着今年4月份将其开源,至今大巨细小已迭代20多个版本,现在用的人也不在少数,可以说很安定了。
2、简介

RxHttp是基于OkHttp的二次封装,并与RxJava做到无缝跟尾,一条链就能发送尽情请求。重要上风以下:
1. 支持Gson、Xml、ProtoBuf、FastJson品级三方数据分析工具
2. 支持Get、Post、Put、Delete等尽情请求方式,可自界说请求方式
3. 支持在Activity/Fragment/View/ViewModel/尽情类中,自动封闭请求
4. 支持同一加解密,且可对单个请求设备能否加解密
5. 支持增加公共参数/头部,且可对单个请求设备能否增加公共参数/头部
6. 史上最文雅的实现文件上传/下载及进度的监听,且支持断点下载
7. 史上最文雅的对毛病同一处置赏罚,且不打破Lambda表达式
8. 史上最文雅的处置赏罚多个BaseUrl及静态BaseUrl
9. 史上最文雅的处置赏罚收集缓存
10. 30秒即可上手,进修本钱极低
gradle依靠
  1. implementation 'com.rxjava.rxhttp:rxhttp:1.3.6'//注解处置赏罚器,天生RxHttp类,即可一条链发送请求annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.3.6'//治理RxJava及生命周期,Activity/Fragment 烧毁,自动封闭未完成的请求implementation 'com.rxjava.rxlife:rxlife:1.1.0'//非必须 按照自己需求挑选Converter  RxHttp默许内置了GsonConverterimplementation 'com.rxjava.rxhttp:converter-jackson:1.3.6'implementation 'com.rxjava.rxhttp:converter-fastjson:1.3.6'implementation 'com.rxjava.rxhttp:converter-protobuf:1.3.6'implementation 'com.rxjava.rxhttp:converter-simplexml:1.3.6'
复制代码
注:kotlin用户,请操纵kapt更换annotationProcessor
缓存功用,请检察:RxHttp 全网Http缓存最优解
3、操纵

3.1、预备工作

RxHttp 要求项目操纵Java 8,请在 app 的 build.gradle 文件中增加以下代码
  1. compileOptions {    sourceCompatibility JavaVersion.VERSION_1_8    targetCompatibility JavaVersion.VERSION_1_8}
复制代码
此时,再Rebuild一下项目(经过Rebuild天生RxHttp类),便可以起头RxHttp的入坑之旅
3.2、设备默许的BaseUrl

经过@DefaultDomain注解设备默许域名,以下:
  1. public class Url {    @DefaultDomain //设备为默许域名    public static String baseUrl = "https://www.wanandroid.com/";}
复制代码
此步伐黑白必须的,这里先先容@DefaultDomain注解的用法,更多有关域名的先容,请检察本文3.6章节----多域名/静态域名
3.3、请求三部曲

先来看看怎样发送一个最简单的请求,以下
  1. RxHttp.get("http://...")  //第一步, 经过get、postXxx、putXxx等方式,肯定请求典范             .asString()           //第二步, 经过asXxx系列方式,肯定返回数据典范        .subscribe(s -> {     //第三步, 定阅回调(此步伐同RxJava定阅观察者)        //请求乐成                                             }, throwable -> {                                          //请求失利                                             });                                                
复制代码
是的,不用猜疑,就是这么简单,垂危的事变说3遍
尽情请求,尽情返回数据典范,皆依照请求三部曲
尽情请求,尽情返回数据典范,皆依照请求三部曲
尽情请求,尽情返回数据典范,皆依照请求三部曲
到这,你已经把握了RxHttp的精华,我们只需服膺请求三部曲,操纵RxHttp就会驾轻就熟。
3.3.1、第一部曲:肯定请求典范

RxHttp内部共供给了14个请求方式,以下:
  1. RxHttp.get(String)              //get请求    参数拼接在url背面RxHttp.head(String)             //head请求   参数拼接在url背面RxHttp.postForm(String)         //post请求   参数以{application/x-www-form-urlencoded}形式提交RxHttp.postJson(String)         //post请求   参数以{application/json; charset=utf-8}形式提交,发送Json工具RxHttp.postJsonArray(String)    //post请求   参数以{application/json; charset=utf-8}形式提交,发送Json数组RxHttp.putForm(String)          //put请求    参数以{application/x-www-form-urlencoded}形式提交RxHttp.putJson(String)          //put请求    参数以{application/json; charset=utf-8}形式提交,发送Json工具RxHttp.putJsonArray(String)     //put请求    参数以{application/json; charset=utf-8}形式提交,发送Json数组RxHttp.patchForm(String)        //patch请求  参数以{application/x-www-form-urlencoded}形式提交RxHttp.patchJson(String)        //patch请求  参数以{application/json; charset=utf-8}形式提交,发送Json工具RxHttp.patchJsonArray(String)   //patch请求  参数以{application/json; charset=utf-8}形式提交,发送Json数组RxHttp.deleteForm(String)       //delete请求 参数以{application/x-www-form-urlencoded}形式提交RxHttp.deleteJson(String)       //delete请求 参数以{application/json; charset=utf-8}形式提交,发送Json工具RxHttp.deleteJsonArray(String)  //delete请求 参数以{application/json; charset=utf-8}形式提交,发送Json数组
复制代码
以上14个请求方式你会发现,实在就6个典范,别离对应是Get、Head、Post、Put、Patch、Delete方式,只是其中Post、Put、Patch、Delete各有3个方式有不同形式的提交方式,只需要按照自己的需求挑选就好。
如以上方式还不能满足你的需求,我们还可以经过@Param注解自界说请求方式,有关注解的操纵,本文后续会具体先容。
注:当挪用xxxForm方式发送请求时,经过setMultiForm()方式大要挪用addFile(String, File)增加文件时,内部会自动将参数以{multipart/form-data}方式提交
增加参数/请求头
肯定请求方式后,我们便可以挪用一系列addXxx()方式增加参数/请求头,以下:
  1. RxHttp.get("/service/...")       //发送get请求    .add("key", "value")         //增加参数    .addAll(new HashMap())     //经过Map增加多个参数    .addHeader("deviceType", "android")     //增加请求头    ...
复制代码
尽情请求,都可挪用以上3个方式增加参数/请求头,固然,在差此外请求方式下,也会有差此外addXxx方式供开辟者挪用。以下:
  1. //postJson请求方式下会有更多addAll等方式可供挪用RxHttp.postJson("/service/...") //发送post Json请求    .addAll(new JsonObject())   //经过json工具增加多个参数    .addAll("{\"height\":180,\"weight\":70}") //经过json字符串增加多个参数    ...//postForm请求方式下会有一系列addFile方式可供挪用RxHttp.postForm("/service/...")  //发送post表单请求    .addFile("file", new File("xxx/1.png")) //增加单个文件    .addFile("fileList", new ArrayList()) //增加多个文件    ...
复制代码
以上只列出了几个常用的addXxx方式,更多方式请下载源码体验。
3.3.2、第二部曲:肯定返回数据典范

增加好参数/请求头后,正式进入第二部曲,肯定返回数据典范,我们经过asXxx方式肯定返回典范,比如,我们要返回一个Student工具,便可以经过asObject(Class)方式,以下:
  1. RxHttp.postForm("/service/...")  //发送post表单请求    .add("key", "value")         //增加参数,可挪用屡次    .asObject(Student.class)    //返回Student典范    .subscribe(student -> {           //请求乐成,这里就能拿到 Student工具                   }, throwable -> {                 //请求失利                    });   
复制代码
假如要返回Student工具列表,则可以经过asList(Class)方式,以下:
  1. RxHttp.postForm("/service/...")  //发送post表单请求    .add("key", "value")         //增加参数,可挪用屡次    .asList(Student.class)       //返回List典范    .subscribe(students -> {           //请求乐成,这里就能拿到 Student工具列表                   }, throwable -> {                 //请求失利                    });   
复制代码
分析Response典范数据
但是,现实开辟中,大大都人的接口,返回的数据结构都类似下面的这个样子
  1. public class Response {    private int    code;    private String msg;    private T      data;    //这里省略get、set方式}
复制代码
对于这类数据结构,按传统的写法,每次都要对code做判定,倘使有100个请求,就要判定100次,真的会逼死逼迫症患者。
RxHttp对于这类情况,给出完善的答案,比如Response里面的T代表一个Student工具,则可以经过asResponse(Class)方式获得,以下:
  1. RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponse(Student.class)    //返回Student典范    .subscribe(student -> {           //请求乐成,这里能拿到 Student工具                   }, throwable -> {                 //请求失利                    });   
复制代码
假如Response里面的T代表一个List列表工具,则可以经过asResponseList(Class)方式获得,以下
  1. RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponseList(Student.class)    //返回List典范    .subscribe(students -> {           //请求乐成,这里能拿到List列表工具                   }, throwable -> {                 //请求失利                    });   
复制代码
更多时候,我们的列表数据是分页的,类似下面的数据结构
  1. {    "code": 0,    "msg": "",    "data": {        "totalPage": 0,        "list": []    }}
复制代码
此时,挪用RxHttp的asResponsePageList(Class)方式仍然可以完善打点,以下:
  1. RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponsePageList(Student.class)    //返回PageList典范    .subscribe(pageList -> {           //请求乐成,这里能拿到PageList列表工具        int totalPage = pageList.getTotalPage();   //总页数       List students = pageList.getData();  //单页列表数据            }, throwable -> {                 //请求失利                    });   
复制代码
到这,估量很多人会问我:

  • 你的code在那边判定的?
  • 我的code是100大要此外值才代表切确,怎样改?
  • 我的Response类里面的字段名,跟你的都纷歧样,怎样该?
  • 你这乐成的时候间接返回Response里面的T,那我还要拿到code做其他的判定,尝试不同营业逻辑,怎样办?
这里可以先告诉大家,asResponse(Class)、asResponseList(Class)、asResponsePageList(Class)这3个方式并不是RxHttp内部供给的,而是经过自界说分析器天生,里面的code判定、Response类都是开辟者自界说的,怎样自界说分析器,请检察本文5.1章节----自界说Parser。
接着答复第4个题目,怎样拿到code做其他的营业逻辑判定,很简单,我们只需用OnError接口处置赏罚毛病回调即可,以下:
  1. RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponse(Student.class)    //返回Student典范    .subscribe(student -> {           //请求乐成,这里能拿到 Student工具                   }, (OnError) error -> {     //留意,这里要用OnError接口,其中error是一个ErrorInfo工具          //失利回调        //拿到code字段,此时便可以对code做判定,尝试差此外营业逻辑         int code = error.getErrorCode();             String errorMsg = error.getErrorMsg()  //拿到msg字段                 });   
复制代码
注:上面的OnError接口并非是RxHttp内部供给的,而是自界说的,在Demo里可以找到
以上先容的5个asXxx方式,可以说底子涵盖80%以上的营业场景,接下来我们看看RxHttp都供给了哪些asXxx方式,以下:

RxHttp内部共供给了23个asXXX方式,其中:

  • 有7个是返回底子典范的包装典范,如:asInteger、asBoolean、asLong等等;
  • 另有7个是返回工具典范,如:asString、asBitmap、asList、asMap(3个)以及最常用asObject方式;
  • 剩下9个是asParser(Parser)、 asUpload系列方式及asDownload系列方式。
duang、duang、duang !!! 划重点,这里我可以告诉大家,实在前面的14个方式,终极都是经过asParser(Parser)方式实现的,具体实现进程,这里先跳过,后续会具体讲授。
3.3.3、第三部曲:定阅回调

这一步就很简单了,在第二部曲中,asXxx方式会返回Observable工具,没错,就是RxJava内部的Observable工具,此时我们即可经过subscribe系列方式定阅回调,以下:
  1. //不处置赏罚任何回调RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponseList(Student.class)    //返回List典范    .subscribe();    //不定阅任何回调    //仅定阅乐成回调RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponseList(Student.class)    //返回List典范    .subscribe(students -> {           //请求乐成,这里能拿到List列表工具                   });        //定阅乐成与失利回调RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponseList(Student.class)    //返回List典范    .subscribe(students -> {           //请求乐成,这里能拿到List列表工具                   }, throwable -> {                 //请求失利                    });    //等等,省略
复制代码
此外,我们还可以定阅请求起头/竣事的回调,以下:
  1. RxHttp.get("/service/...")    .asString()    .observeOn(AndroidSchedulers.mainThread())    .doOnSubscribe(disposable -> {        //请求起头,当前在主线程回调    })    .doFinally(() -> {        //请求竣事,当前在主线程回调    })    .as(RxLife.as(this))  //感知生命周期    .subscribe(pageList -> {        //乐成回调,当前在主线程回调    }, (OnError) error -> {        //失利回调,当前在主线程回调    });
复制代码
到这,请求三部曲先容终了,接着,将先容此外常用的功用
3.4、初始化
  1. //设备debug形式,默以为false,设备为true后,发请求,过滤"RxHttp"能看到请求日志RxHttp.setDebug(boolean debug)//非必须,只能初始化一次,第二次将抛出很是RxHttp.init(OkHttpClient okHttpClient)//大要,调试形式下会有日志输出RxHttp.init(OkHttpClient okHttpClient, boolean debug)
复制代码
此步伐黑白必须的,如需要增加阻挡器等其他营业需求,则可挪用init方式举行初始化,不初始化大要传入null即代表操纵默许OkHttpClient工具,倡议在Application中初始化,默许的OkHttpClient工具在HttpSender类中可以找到,以下:
  1. private static OkHttpClient getDefaultOkHttpClient() {                                  X509TrustManager trustAllCert = new X509TrustManagerImpl();                         SSLSocketFactory sslSocketFactory = new SSLSocketFactoryImpl(trustAllCert);         return new OkHttpClient.Builder()                                                       .connectTimeout(10, TimeUnit.SECONDS)                                               .readTimeout(10, TimeUnit.SECONDS)                                                  .writeTimeout(10, TimeUnit.SECONDS)                                                 .sslSocketFactory(sslSocketFactory, trustAllCert) //增加信任证书                          .hostnameVerifier((hostname, session) -> true) //疏忽host考证                           .build();                                                                   }                                                                                   
复制代码
固然初始化黑白必须的,可是倡议大家传入自界说的OkHttpClient工具,一来,自界说的OkHttpClient能最大化满足本身的营业;二来,随着RxHttp版本的升级,默许的OkHttpClient大要会发生变革(固然大要性很小),故倡议自界说OkHttpClient工具传入RxHttp。
3.5、公共参数/请求头

RxHttp支持为全数的请求增加公共参数/请求头,固然,假如你渴望某个请求不增加公共参数/请求头,也是支持的,而且很是简单。以下:
  1. RxHttp.setOnParamAssembly(new Function() {    @Override    public Param apply(Param p) { //此方式在子线程中尝试,即请求倡议线程        Method method = p.getMethod();        if (method.isGet()) {     //可按照请求典范增加差此外参数        } else if (method.isPost()) {        }        return p.add("versionName", "1.0.0")//增加公共参数                .addHeader("deviceType", "android"); //增加公共请求头    }});
复制代码
我们需要挪用RxHttp.setOnParamAssembly(Function)方式,并传入一个Function接口工具,每次倡议请求,城市回调该接口。
固然,假如渴望某个请求不回调该接口,即不增加公共参数/请求头,则可以挪用setAssemblyEnabled(boolean)方式,并传入false即可,以下:
  1. RxHttp.get("/service/...")       //get请求     .setAssemblyEnabled(false)   //设备能否增加公共参数/头部,默以为true        .asString()                  //返回字符串数据        .subscribe(s -> {            //这里的s为String典范        //请求乐成                                             }, throwable -> {                                          //请求失利                                             });                                                
复制代码
3.6、多域名/静态域名

3.6.1、多域名
现实开辟中,我们经常会碰到多个域名的情况,其中1个为默许域名,此外为非默许域名,对于这类情况,RxHttp供给了@DefaultDomain()、@Domain()这两个注解来标明默许域名和非默许域名,以下:
  1. public class Url {    @DefaultDomain() //设备为默许域名    public static String baseUrl = "https://www.wanandroid.com/"        @Domain(name = "BaseUrlBaidu") //非默许域名,并取别名为BaseUrlBaidu    public static String baidu = "https://www.baidu.com/";        @Domain(name = "BaseUrlGoogle") //非默许域名,并取别名为BaseUrlGoogle    public static String google = "https://www.google.com/";}
复制代码
经过@Domain()注解标注非默许域名,就会在RxHttp类中天生setDomainToXxxIfAbsent()方式,其中Xxx就是注解中取的别名。
上面我们操纵了两个@Domain()注解,此时(需要Rebuild一下项目)就会在RxHttp类中天生setDomainToBaseUrlBaiduIfAbsent()、setDomainToBaseUrlGoogleIfAbsent()这两方式,此时发请求,我们便可以操纵指定的域名,以下:
  1. //操纵默许域名,则无需增加任何额外代码//此时 url = "https://www.wanandroid.com/service/..." RxHttp.get("/service/...")    .asString()      .subscribe();    //手动输入域名,此时 url = "https://www.mi.com/service/..."RxHttp.get("https://www.mi.com/service/...")    .asString()      .subscribe();//手动输入域名时,若再次指定域名,则无效//此时 url = "https://www.mi.com/service/..."RxHttp.get("https://www.mi.com/service/...")    .setDomainToBaseUrlBaiduIfAbsent()  //此时指定Baidu域名无效    .asString()      .subscribe();    //操纵谷歌域名,此时 url = "https://www.google.com/service/..."       RxHttp.get("/service/...")    .setDomainToBaseUrlGoogleIfAbsent() //指定操纵Google域名    .asString()      .subscribe();
复制代码
经过以上案例,可以晓得,RxHttp共有3种指定域名的方式,按优先级排名别离是:手动输入域名 > 指定非默许域名 > 操纵默许域名。
3.6.2、静态域名
现实开辟中,也会有静态域名切换的需求,如域名被封、大要需要按照办事端下发的域名去设备,这对于RxHttp来说简直就是 so easy !!! 我们只需要对BaseUrl重新赋值,此时发请求便会立即生效,以下:
  1. //此时 url = "https://www.wanandroid.com/service/..."RxHttp.get("/service/...")    .asString()      .subscribe();    Url.baseUrl = "https://www.qq.com"; //静态变动默许域名,改完立即生效,非默许域名同理//此时 url = "https://www.qq.com/service/..."RxHttp.get("/service/...")    .asString()      .subscribe();
复制代码
3.7、封闭请求

我们晓得,在Activity/Fragment中倡议请求,假如页面烧毁时,请求还未竣事,就会有内存泄漏的危险,是以,我们需要在页面烧毁时,封闭一些还未完成的请求,RxHttp供给了两种封闭请求的方式,别离是自动+手动。
3.7.1、自动封闭请求
自动封闭请求,需要引入本人开源的另一个库RxLife,先来看看怎样用:
  1. //以下代码均在FragmentActivty/Fragment中挪用RxHttp.postForm("/service/...")    .asString()    .as(RxLife.as(this)) //页面烧毁、自动封闭请求    .subscribe();    //大要RxHttp.postForm("/service/...")    .asString()    .as(RxLife.asOnMain(this)) //页面烧毁、自动封闭请求 而且在主线程回调观察者    .subscribe();//kotlin用户,请操纵life或lifeOnMain方式,以下:RxHttp.postForm("/service/...")    .asString()    .life(this) //页面烧毁、自动封闭请求    .subscribe();    //大要RxHttp.postForm("/service/...")    .asString()    .lifeOnMain(this) //页面烧毁、自动封闭请求 而且在主线程回调观察者    .subscribe();
复制代码
上面的this为LifecycleOwner接口工具,我们的FragmentActivity/Fragment均实现了这个接口,全数我们在FragmentActivity/Fragment中可以间接传this。
对RxLife不了解的同学请检察RxLife 史上最文雅的治理RxJava生命周期,这里不具体讲授。
3.7.2、手动封闭请求
手动封闭请求,我们只需要在定阅回调的时候拿到Disposable工具,经过该工具可以判定请求能否竣事,假如没有,便可以封闭请求,以下:
  1. //定阅回调,可以拿到Disposable工具Disposable disposable = RxHttp.get("/service/...")    .asString()      .subscribe(s -> {        //乐成回调    }, throwable -> {       //失利回调    });    if (!disposable.isDisposed()) {  //判定请求有没有竣事    disposable.dispose();       //没有竣事,则封闭请求}                              
复制代码
3.8、文件上传/下载/进度监听

RxHttp可以很是文雅的实现上传/下载及进度的监听,是骡子是马,拉出来溜溜
3.8.1上传
经过addFile系列方式增加文件,以下:
  1. RxHttp.postForm("/service/...") //发送Form表单形式的Post请求      .addFile("file1", new File("xxx/1.png"))  //增加单个文件          .addFile("fileList", new ArrayList())   //经过List工具,增加多个文件         .asString()                                          .subscribe(s -> {                                      //上传乐成                                         }, throwable -> {                                      //上传失利                                         });                                            
复制代码
经过asUpload系列方式监听上传进度,以下:
  1. RxHttp.postForm("/service/...") //发送Form表单形式的Post请求                                        .addFile("file1", new File("xxx/1.png"))                                             .addFile("file2", new File("xxx/2.png"))                                             .asUpload(progress -> {                                                                  //上传进度回调,0-100,仅在进度有更新时才会回调                                                          int currentProgress = progress.getProgress(); //当进步度 0-100                           long currentSize = progress.getCurrentSize(); //当前已上传的字节巨细                           long totalSize = progress.getTotalSize();     //要上传的总字节巨细                        }, AndroidSchedulers.mainThread())   //指定回调(进度/乐成/失利)线程,不指定,默许在请求地点线程回调                                               .subscribe(s -> {                                                                        //上传乐成                                                                           }, throwable -> {                                                                        //上传失利                                                                           });                                                                              
复制代码
可以看到,跟上传的代码相比,我们仅仅是操纵了asUpload(Consumer, Scheduler)方式更换asString()方式,第一个参数是进度监听接口,每当进度有更新时,城市回调该接口,第二个参数是指定回调的线程,这里我们指定了在UI线程中回调。
3.8.2、下载
下载操纵asDownload(String)方式,传入当地途径即可
  1.   //文件存储途径String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")    .asDownload(destPath) //留意这里操纵asDownload操纵符,并传入当地途径    .subscribe(s -> {        //下载乐成,回调文件下载途径    }, throwable -> {        //下载失利    });
复制代码
3.8.3、带进度下载
带进度下载操纵asDownload(String,Consumer,Scheduler)方式
  1.   //文件存储途径String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")    .asDownload(destPath, progress -> {        //下载进度回调,0-100,仅在进度有更新时才会回调,最多回调101次,末端一次回调文件存储途径        int currentProgress = progress.getProgress(); //当进步度 0-100        long currentSize = progress.getCurrentSize(); //当前已下载的字节巨细        long totalSize = progress.getTotalSize();     //要下载的总字节巨细    }, AndroidSchedulers.mainThread()) //指定主线程回调    .subscribe(s -> {//s为String典范,这里为文件存储途径        //下载完成,处置赏罚相关逻辑    }, throwable -> {        //下载失利,处置赏罚相关逻辑    });
复制代码
3.8.4、断点下载
断点下载相较于下载,仅需要挪用setRangeHeader(long startIndex, long endIndex)方式传入起头及竣事位置即可(竣事位置不传默以为文件结尾),此外没有任何不同
  1. String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";long length = new File(destPath).length(); //已下载的文件长度RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")    .setRangeHeader(length)  //设备起头下载位置,竣事位置默以为文件结尾    .asDownload(destPath)    .subscribe(s -> { //s为String典范        //下载乐成,处置赏罚相关逻辑    }, throwable -> {        //下载失利,处置赏罚相关逻辑    });
复制代码
3.8.5、带进度断点下载
带进度断点下载相较于带进度下载仅需要挪用setRangeHeader方式传入起头及竣事位置即可(竣事位置不传默以为文件结尾),此外没有任何不同
  1. String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";long length = new File(destPath).length(); //已下载的文件长度RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")    .setRangeHeader(length)  //设备起头下载位置,竣事位置默以为文件结尾    .asDownload(destPath, progress -> {        //下载进度回调,0-100,仅在进度有更新时才会回调        int currentProgress = progress.getProgress(); //当进步度 0-100        long currentSize = progress.getCurrentSize(); //当前已下载的字节巨细        long totalSize = progress.getTotalSize();     //要下载的总字节巨细    }, AndroidSchedulers.mainThread()) //指定主线程回调    .subscribe(s -> { //s为String典范        //下载乐成,处置赏罚相关逻辑    }, throwable -> {        //下载失利,处置赏罚相关逻辑    });
复制代码
注:上面带进度断点下载中,返回的进度会从0起头,假如需要跟尾上次下载的进度,则挪用asDownload(String,long,Consumer,Scheduler)方式传入上次已经下载好的长度(第二个参数),以下:
  1. String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";long length = new File(destPath).length(); //已下载的文件长度RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")    .setRangeHeader(length)  //设备起头下载位置,竣事位置默以为文件结尾    .asDownload(destPath, length, progress -> {        //下载进度回调,0-100,仅在进度有更新时才会回调        int currentProgress = progress.getProgress(); //当进步度 0-100        long currentSize = progress.getCurrentSize(); //当前已下载的字节巨细        long totalSize = progress.getTotalSize();     //要下载的总字节巨细    }, AndroidSchedulers.mainThread()) //指定主线程回调    .subscribe(s -> { //s为String典范        //下载乐成,处置赏罚相关逻辑    }, throwable -> {        //下载失利,处置赏罚相关逻辑    });
复制代码
3.9、超时设备

3.9.1、设备全局超时
RxHttp内部默许的读、写、毗连超不时候均为10s,如需点窜,请自界说OkHttpClient工具,以下:
  1. //设备读、写、毗连超不时候为15sOkHttpClient client = new OkHttpClient.Builder()    .connectTimeout(15, TimeUnit.SECONDS)    .readTimeout(15, TimeUnit.SECONDS)    .writeTimeout(15, TimeUnit.SECONDS)    .build();RxHttp.init(client);
复制代码
3.9.2、为单个请求设备超时
为单个请求设备超时,操纵的是RxJava的timeout(long timeout, TimeUnit timeUnit)方式,以下:
  1. RxHttp.get("/service/...")    .asString()    .timeout(5, TimeUnit.SECONDS)//设备总超不时候为5s    .as(RxLife.asOnMain(this))  //感知生命周期,并在主线程回调    .subscribe(pageList -> {        //乐成回调    }, (OnError) error -> {        //失利回调    });
复制代码
注:这里设备的总超不时候要小于全局读、写、毗连超不时候之和,否则无效
3.10、设备Converter

3.10.1、设备全局Converter
  1. IConverter converter = FastJsonConverter.create();RxHttp.setConverter(converter)
复制代码
3.10.2、为请求设备零丁的Converter
首先需要在尽情public类中经过@Converter注解声明Converter,以下:
  1. public class RxHttpManager {    @Converter(name = "XmlConverter") //指定Converter称号    public static IConverter xmlConverter = XmlConverter.create();}
复制代码
然后,rebuild 一下项目,就在自动在RxHttp类中天生setXmlConverter()方式,随后便可以挪用此方式为单个请求指定Converter,以下:
  1. RxHttp.get("/service/...")    .setXmlConverter()   //指定操纵XmlConverter,不指定,则操纵全局的Converter    .asObject(NewsDataXml.class)    .as(RxLife.asOnMain(this))  //感知生命周期,并在主线程回调    .subscribe(dataXml -> {        //乐成回调    }, (OnError) error -> {        //失利回调    });
复制代码
3.11、请求加解密

3.11.1、加密
请求加密,需要自界说Param,很是简单,详情请检察本文5.2章节----自界说Param
3.11.2、解密
有些时候,请求会返回一大串的密文,此时就需要将密文转化为明文,间接来看代码,以下:
  1. //设备数据解密/解码器                                               RxHttp.setResultDecoder(new Function() {    //每次请求乐成,城市回调这里,并传入请求返回的密文       @Override                                                  public String apply(String s) throws Exception {           String plaintext = decode(s);   //将密文解密成明文,解密逻辑自己实现        return plaintext;    //返回明文                                       }                                                      });                                                        
复制代码
很简单,经过RxHttp.setResultDecoder(Function)静态方式,传入一个接口工具,此接口会在每次请求乐成的时候被回调,并传入请求返回的密文,只需要将密文解密后返回即可。
但是,有些请求是不需求解密的,此时便可以挪用setDecoderEnabled(boolean)方式,并传入false即可,以下:
  1. RxHttp.get("/service/...")    .setDecoderEnabled(false)  //设备本次请求不需要解密,默以为true    .asString()    .subscribe(pageList -> {        //乐成回调    }, (OnError) error -> {        //失利回调    });
复制代码
3.12、指定请求/回调线程

RxHttp默许在Io线程尝试请求,也默许在Io线程回调,即默许在同一Io线程尝试请求并回调,固然,我们也可以指定请求/回调地点线程。
3.12.1、指定请求地点线程
我们可以挪用一些列subscribeXxx方式指定请求地点线程,以下:
  1. //指定请求地点线程,需要在第二部曲前尽情位置挪用,第二部曲后挪用无效RxHttp.get("/service/...")    .subscribeOnCurrent() //指定在当前方程尝试请求,即同步尝试,    .asString()      .subscribe();//此外subscribeXxx方式subscribeOnIo()   //RxHttp默许的请求线程subscribeOnSingle()subscribeOnNewThread()subscribeOnComputation()subscribeOnTrampoline()subscribeOn(Scheduler) //自界说请求线程
复制代码
以上操纵的皆是RxJava的线程调节器,不熟悉的请自行查阅相关材料,这里不做具体先容。
3.12.2、指定回调地点线程
指定回调地点线程,仍然操纵RxJava的线程调节器,以下:
  1. //指定回调地点线程,需要在第二部曲后挪用RxHttp.get("/service/...")    .asString()      .observeOn(AndroidSchedulers.mainThread()) //指定在主线程回调    .subscribe(s -> { //s为String典范,主线程回调        //乐成回调    }, throwable -> {        //失利回调    });
复制代码
3.13、 Retrofit用户

经常会有童鞋问我,我是Retrofit用户,喜好把接口写在一个类里,然后可以间接挪用,RxHttp怎样实现?实在,这个题目压根就不是题目,在先容第二部曲的时候,我们晓得,操纵asXxx方式后,就会返回Observable工具,是以,我们便可以这样实现:
  1. public class HttpWrapper {    public static Observable getStudent(int page) {        return RxHttp.get("/service/...")            .add("page", page)            .asList(Student.class);    }}//随后在此外地方便可以间接挪用HttpWrapper.getStudent(1)    .as(RxLife.asOnMain(this))  //主线程回调,并在页面烧毁自动封闭请求(假如还未封闭的话)    .subscribe(students -> { //门生列表        //乐成回调    }, throwable -> {        //失利回调    });
复制代码
很简单,封装的时候返回Observable工具即可。
另有的同学问,我们获得列表的接口,页码是和url拼接在一路的,Retrofit可以经过占位符,那RxHttp又怎样实现?简单,以下:
  1. public class HttpWrapper {    //单个占位符    public static Observable getStudent(int page) {        return RxHttp.get("/service/%d/...", page)  //操纵标准的占位符协议            .asObject(Student.class);    }        //多个占位符    public static Observable getStudent(int page, int count) {        return RxHttp.get("/service/%1$d/%2$d/...", page, count)  //操纵标准的占位符协议            .asObject(Student.class);    }}
复制代码
这一点跟Retrofit不同,Retrofit是经过注解指定占位符的,而RxHttp是操纵标准的占位符,我们只需要在url中声明占位符,随后在传入url的背面,带上对应的参数即可。
4、道理分析

4.1、工作流程

在RxHttp有4个垂危的脚色,别离是:

  • Param:RxHttp类中全数增加的参数/请求头/文件都交由它处置赏罚,它终纵方针就是为了构建一个Request工具
  • HttpSender :它负责从Param工具中拿到Request工具,从而尝试请求,终极返回Response工具
  • Parser:它负责将HttpSender返回的Response工具,分析成我们盼望的实体类工具,也就是泛型T
  • RxHttp:它像一个管家,批示前面3个脚色办事变,固然,它也有自己的事变要做,比如:请求线程的调节,BaseUrl的处置赏罚、答应开辟者自界说API等等
为此,我画了一个流程图,可以直观的了解到RxHttp的大略工作流程

我想应当很好大白,RxHttp要做的事变,就是把增加的参数/请求甲等全数丢给Param处置赏罚,自己啥事也不敢;随后将Param交给HttpSender,让它去尝试请求,尝试终了,返回Response工具;接着又将Response工具丢给Parser去做数据分析工作,并返回实体类工具T;末端,将T经过回调传给开辟者,到此,一个请求就处置赏罚完成。
4.2、Param

首先,附上一张Param类的继续关系图

下面将从上往下对上图中的类做个简单的先容:

  • IHeaders:接口类,里面界说了一系列addHeader方式
  • IParam:接口类,里面界说了add(String,Object)、addAll(Map)等方式,
  • IRequest:接口类,里面界说了一系列getXxx方式,经过这些方式终极构建一个Request工具
  • Param:接口类,是一个空接口,继续了前面3个接口,里面有一系列静态方式可以获得到Param的具体实现类
  • AbstractParam:Param接口的笼统实现类,实现了Param接口的全数方式
  • IFile:接口类,里面界说了一系列addFile方式
  • IUploadLengthLimit:接口类,里面就界说了一个checkLength()方式,用于限制文件上传巨细
  • NoBodyParam:Param的具体实现类,Get、Head请求就是经过该类去实现的
  • JsonParam:Param的具体实现类,挪用RxHttp.xxxJson(String)请求方式时,内部就是经过该类去实现的
  • JsonArrayParam:Param的具体实现类,挪用RxHttp.xxxJsonArray(String)请求方式时,内部就是经过该类去实现的
  • FormParam:Param的具体实现类,同时又实现了IFile、IUploadLengthLimit两个接口,挪用RxHttp.xxxForm(String)请求方式时,内部就是经过该类去实现的
4.3、HttpSender

HttpSender可以把它大白为请求发送者,里面声明OkHttpClient工具和一系列静态方式,我们来简单看下:
  1. public final class HttpSender {    private static OkHttpClient mOkHttpClient; //只能初始化一次,第二次将抛出很是    //处置赏罚化OkHttpClient工具    public static void init(OkHttpClient okHttpClient) {        if (mOkHttpClient != null)            throw new IllegalArgumentException("OkHttpClient can only be initialized once");        mOkHttpClient = okHttpClient;    }    //经过Param工具同步尝试一个请求    public static Response execute(@NonNull Param param) throws IOException {        return newCall(param).execute();    }    static Call newCall(Param param) throws IOException {        return newCall(getOkHttpClient(), param);    }    //全数的请求,终极城市调此方式拿到Call工具,然后尝试请求    static Call newCall(OkHttpClient client, Param param) throws IOException {        param = RxHttpPlugins.onParamAssembly(param);        if (param instanceof IUploadLengthLimit) {            ((IUploadLengthLimit) param).checkLength();        }        Request request = param.buildRequest();  //经过Param拿到Request工具        LogUtil.log(request);        return client.newCall(request);    }    //省略了部分方式}
复制代码
这里我们重点看下newCall(OkHttpClient, Param)方式,该方式第一行就是为Param增加公共参数;然后判定Param有没有实现IUploadLengthLimit接口,有的话,检查文件上传巨细,超越巨细,则抛出IO很是;接着就是经过Param拿到Request工具;末端拿到Call工具,便可以发送一个请求。
4.4、Parser

先看下Parser继续结构图

这里对上图中的类做个简单的先容

  • Parser:接口类,里面界说了一个T onParse(Response)方式,输入Response工具,输出实体类工具T
  • AbstractParser:笼统类,里面没有任何具体实现,重要感化是在机关方式内获得泛型典范
  • SimpleParser:是一个万能的分析器,可以分析尽情数据结构,RxHttp内置的大部分asXxx方式,内部就是经过该分析器实现的
  • ListParser:是一个列表分析器,可以分析尽情列表数据,内置asList(Class)方式,就是经过该分析器实现的
  • MapParser:是一个Map分析器,可以分析尽情Map数据典范,内置的asMap系列方式,就是经过该分析器实现的
  • BitmapParser:是一个Bitmap分析器,经过该分析器可以获得一个Bitmap工具,asBitmap()方式内部就是经过该分析器实现的
  • DownloadParser:文件下载分析器,用于文件下载,内置的一系列asDownload方式就是经过该分析器实现的
5、扩大

5.1、自界说Parser

前面第二部曲中,我们先容了一系列asXxx方式,经过该系列方式可以很方便的指定数据返回典范,特别是自界说的asResponse(Class)、asResponseList(Class)、asResponsePageList(Class)这3个方式,将Reponse典范数据,处置赏罚的简直不要太完善,下面我们就来看看怎样自界说Parser。
源码永久是最好的进修方式,在进修自界说Parser前,我们无妨先看看内置的Parser是怎样实现的
SimPleParser
  1. public class SimpleParser extends AbstractParser {    //省略机关方式    @Override    public T onParse(Response response) throws IOException {        return convert(response, mType);    }}
复制代码
可以看到,SimpleParser除了机关方式,就剩一个onParser方式,该方式是在Parser接口中界说的,再来看看具体的实现convert(Response, Type),这个方式也是在Parser接口中界说的,而且有默许的实现,以下:
  1. public interface Parser {    //输入Response 输出T    T onParse(@NonNull Response response) throws IOException;    //对Http返回的结果,转换成我们盼望的实体类工具    default  R convert(Response response, Type type) throws IOException {        ResponseBody body = ExceptionHelper.throwIfFatal(response);  //这里内部会判定code=300 时,抛出很是        boolean onResultDecoder = isOnResultDecoder(response); //能否需要对返回的数据举行解密        LogUtil.log(response, onResultDecoder, null);        IConverter converter = getConverter(response);        //取出转换器        return converter.convert(body, type, onResultDecoder); //对数据进场转换    }    //省略几多方式}
复制代码
可以看到,很是的简单,输入Response工具和泛型典范Type,内部就经过IConverter接口转换为我们盼望的实体类工具并返回。
到这,我想大家应当就几多有点大白了,自界说Parser,不过就是继续AbstractParser,然后实现onParser方式即可,那我们来考证一下,我们来看看内置ListParser能否是这样实现的,以下:
  1. public class ListParser extends AbstractParser {    //省略机关方式    @Override    public List onParse(Response response) throws IOException {        final Type type = ParameterizedTypeImpl.get(List.class, mType); //拿到泛型典范        return convert(response, type);    }}
复制代码
可以看到,跟SimpleParser分析器几乎是一样的实现,不同是的,这里将我们输入的泛型T与List组拼为一个新的泛型典范,终极返回List工具。
现在,我们便可以来自界说Parser了,先来自界说ResponseParser,用来处置赏罚Response数据典范,先看看数据结构:
  1. public class Response {    private int    code;    private String msg;    private T      data;    //这里省略get、set方式}
复制代码
自界说ResponseParser代码以下:
  1. //经过@Parser注解,为分析器取别名为Response,此时就会在RxHttp类天生asResponse(Class)方式@Parser(name = "Response") public class ResponseParser extends AbstractParser {    //省略机关方式    @Override    public T onParse(okhttp3.Response response) throws IOException {        final Type type = ParameterizedTypeImpl.get(Response.class, mType); //获得泛型典范        Response data = convert(response, type);        T t = data.getData(); //获得data字段        if (data.getCode() != 0 || t == null) {//这里假定code未即是0,代表数据不切确,抛出很是            throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);        }        return t;    }}
复制代码
可以看到,很是的简单,首先将我们输入泛型和自界说的Response类组拼成新的泛型典范,随后经过convert(Response, Type)方式获得Response工具,接着又对code及T做了判定,假如不切确就抛出很是,末端返回T。
估量这里有人会问,我怎样用这个分析器呢?信任很多小同伴以及发现了,我们在ResponseParser类名上面用了@Parser注解,只要用了该注解,就会在RxHttp自动天生asXxx(Class)方式,其中Xxx就是我们在@Parser注解中为分析器取的别名,这里取别名为Response,所以便会在RxHttp类中自动天生asResponse(Class)方式,以下:
  1.   public  Observable asResponse(Class type) {    return asParser(new ResponseParser(type));  }
复制代码
可以看到,该方式内部又挪用了asParser(Parser)方式,并传入了ResponseParser,是以,我们有两种方式操纵自界说的ResponseParser,以下:
  1. //第一种方式,操纵@parser注解天生的asResponse方式RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asResponse(Student.class)    //返回Student典范    .subscribe(student -> {           //请求乐成,这里能拿到 Student工具                   }, throwable -> {                 //请求失利                    });   //第二种方式,间接操纵asParser(Parser)方式RxHttp.postForm("/service/...")   //发送post表单请求    .add("key", "value")          //增加参数,可挪用屡次    .asParser(new ResponseParser(){})    //返回Student典范    .subscribe(student -> {           //请求乐成,这里能拿到 Student工具                   }, throwable -> {                 //请求失利                    });  
复制代码
以上两种方式,除了写法上的区分,此外都一样,用哪类,看小我喜好,但还是倡议操纵第一种方式,不但写法简单,也低落了耦合。
这里末端再贴上ResponseListParser、ResponsePageListParser的源码,道理都是一样的,代码实现也差不多,就不再详解
ResponseListParser
  1. @Parser(name = "ResponseList")public class ResponseListParser extends AbstractParser {    //省略机关方式    @Override    public List onParse(okhttp3.Response response) throws IOException {        final Type type = ParameterizedTypeImpl.get(Response.class, List.class, mType); //获得泛型典范        Response data = convert(response, type);        List list = data.getData(); //获得data字段        if (data.getCode() != 0 || list == null) {  //code未即是0,说明数据不切确,抛出很是            throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);        }        return list;    }}
复制代码
ResponsePageListParser
  1. @Parser(name = "ResponsePageList")public class ResponsePageListParser extends AbstractParser {          //省略机关方式    @Override    public PageList onParse(okhttp3.Response response) throws IOException {        final Type type = ParameterizedTypeImpl.get(Response.class, PageList.class, mType); //获得泛型典范        Response data = convert(response, type);        PageList pageList = data.getData(); //获得data字段        if (data.getCode() != 0 || pageList == null) {  //code未即是0,说明数据不切确,抛出很是            throw new ParseException(String.valueOf(data.getCode()), data.getMsg(), response);        }        return pageList;    }}
复制代码
5.2、自界说Param

自界说Param,想较于自界说Parser,要加倍的简单,我们只需按照自己的需求,继续NoBodyParam、FormParam、JsonParam等,增加大要重写方式即可,比如我们有以下3种情况,需要自界说Param,以下:

  • postForm请求,需要将全数增加的参数,拼接在一路,随后加密,末端将加密的字符串增加到请求头中
  • postJson请求,需要将全数的参数,也就是json字符串加密后再发送进来
  • FormParam里面的API不够用,我要自界说API
5.2.1、postForm请求加密

这类情况,我们需要继续FormParam,并重写getRequestBody()方式,以下:
  1. @Param(methodName = "postEncryptForm")public class PostEncryptFormParam extends FormParam {    public PostEncryptFormParam(String url) {        super(url, Method.POST);  //Method.POST代表post请求    }    @Override    public RequestBody getRequestBody() {        //这里拿到你增加的全数参数        List keyValuePairs = getKeyValuePairs();        String encryptStr = "加密后的字符串";  //按照上面拿到的参数,自行实现加密逻辑        addHeader("encryptStr", encryptStr);        return super.getRequestBody();    }}
复制代码
5.2.2、postJson请求加密

这类情况,我们需要继续JsonParam,也重写getRequestBody()方式,以下:
  1. @Param(methodName = "postEncryptJson")public class PostEncryptJsonParam extends JsonParam {    public PostEncryptFormParam(String url) {        super(url, Method.POST);    }    @Override    public RequestBody getRequestBody() {        //这里拿到你增加的全数参数        Map params = getParams();        String encryptStr = "加密后的字符串";  //按照上面拿到的参数,自行实现解密逻辑        return RequestBody.create(MEDIA_TYPE_JSON, encryptStr);  //发送加密后的字符串    }}
复制代码
5.2.3、自界说API

我们继续FormParam,并新增两个test方式`,以下:
  1. @Param(methodName = "postTestForm")public class PostTestFormParam extends FormParam {    public PostEncryptFormParam(String url) {        super(url, Method.POST);    }        public PostEncryptFormParam test(long a, float b) {        //这里的营业逻辑自行实现        return this;    }        public PostEncryptFormParam test1(String s, double b) {        //这里的营业逻辑自行实现        return this;    }}
复制代码
5.2.4、操纵自界说的Param

一样的题目,我们怎样用这3个自界说的Param呢?我想大大都人在类名前发现类@Param注解,并为Param取了别名。那这个又有什么感化呢?
答案颁发,只要在自定的Param上操纵了@Param注解,并取了别名,就会在RxHttp类自动天生一个跟别名一样的方式,在上面我们自界说了3个Param,并别离取别名为postEncryptForm、postEncryptJson、postTestForm,此时就会在RxHttp类中天生postEncryptForm(String)、postEncryptJsonString)、postTestForm(String)这3个方式,我们在RxHttp这个类中来看下:
  1.   public static RxHttp$PostEncryptFormParam postEncryptForm(String url) {    return new RxHttp$PostEncryptFormParam(new PostEncryptFormParam(url));  }    public static RxHttp$PostEncryptJsonParam postEncryptJson(String url) {    return new RxHttp$PostEncryptJsonParam(new PostEncryptJsonParam(url));  }  public static RxHttp$PostTestFormParam postTestForm(String url) {    return new RxHttp$PostTestFormParam(new PostTestFormParam(url));  }
复制代码
发请求时,只需要挪用对应的方式就好,如:
  1. //发送加密的postForm请求RxHttp.postEncryptForm("/service/...")       .add("key", "value")          //增加参数,可挪用屡次    .asString()                  //返回String典范    .subscribe(s-> {           //请求乐成        }, throwable -> {                 //请求失利                    });      //发送加密的postJson请求RxHttp.postEncryptJson("/service/...")       .add("key", "value")          //增加参数,可挪用屡次    .asString()                  //返回String典范    .subscribe(s-> {           //请求乐成        }, throwable -> {                 //请求失利                    });  
复制代码
那我自界说的API怎样挪用呢,so easy!!!!,挑选对应的请求方式后,便可以间接挪用,以下:
  1. //发送加密的postJson请求RxHttp.postTestJson("/service/...")       .test(100L, 99.99F)          //挪用自界说的API    .test1("testKey", 88.88D)    //挪用自界说的API    .add("key", "value")         //增加参数,可挪用屡次    .asString()                  //返回String典范    .subscribe(s-> {           //请求乐成        }, throwable -> {                 //请求失利                    });  
复制代码
5.3、自界说Converter

RxHttp内部默许操纵来GsonConverter,而且额外供给了4个Converter,以下:
  1. //非必须 按照自己需求挑选Converter  RxHttp默许内置了GsonConverterimplementation 'com.rxjava.rxhttp:converter-jackson:1.3.6'implementation 'com.rxjava.rxhttp:converter-fastjson:1.3.6'implementation 'com.rxjava.rxhttp:converter-protobuf:1.3.6'implementation 'com.rxjava.rxhttp:converter-simplexml:1.3.6'
复制代码
5.3.1、自界说TestConverter

即使这样,RxHttp也没法保证满足全数的营业需求,为此,我们可以挑选自界说Converter,自界说Converter需要继续IConverter接口,以下:
  1. public class TestConverter implements IConverter {    /**     * 请求乐成后会被回调     * @param body             ResponseBody     * @param type             泛型典范     * @param onResultDecoder  能否需要对结果举行解码/解密     */    @Override    public  T convert(ResponseBody body, Type type, boolean onResultDecoder) throws IOException {        //自行实现相关逻辑        return null;    }    /**     * json请求前会被回调,需要自行按照泛型T建立RequestBody工具,并返回     */    @Override    public  RequestBody convert(T value) throws IOException {        //自行实现相关逻辑        return null;    }}
复制代码
以上两个convert方式按照本身营业需求自行实现,可以参考RxHttp供给FastJsonConverter、SimpleXmlConverter等Converter
5.3.2、怎样用Converter

请检察本文3.10章节----设备Converter
6、小本事

在这教大家一个小本事,由于操纵RxHttp发送请求都依照请求三部曲,故我们可以在android studio 设备代码模版,以下

如图设备好后,写代码时,输入rp,就会自动天生模版,以下:

7、小结

到这,RxHttp常勤劳能先容终了,你会发现,齐全都是那末的精彩,不管你是get、post、加密请求、自界说分析器,还是文件上传/下载/进度监听等等,皆依照请求三部曲。特别是对Response典范数据处置赏罚,可以说是完善无缺,我们无需每次都判定code,间接便可以拿到T,简直了。。。
末端,喜好的,请给本文点个赞,假如可以,还请给个star,创作不易,感激涕零。

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|理想论坛_专业20年的财经股票炒股论坛交流社区 - 股票论坛

GMT+8, 2020-7-12 19:23 , Processed in 0.293626 second(s), 29 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表