前言
在前面3篇文章中,我们对RxHttp做了整体的介绍,并带领大家自定义Parser及Param,如果还没阅读,请查看
如果还未阅读前面两篇文章,请查看
RxHttp库已更新至1.0.3版本,详情请查看RxHttp 源码
这篇文章将介绍如何使用注解自定义API
Gradle 依赖
implementation 'com.rxjava.rxhttp:rxhttp:1.0.3'
//注解处理器,生成RxHttp类
annotationProcessor 'com.rxjava.rxhttp:rxhttp-compiler:1.0.3'
复制代码
简介
在前面几片文章,有读者疑问,为啥要通过注解来生成RxHttp类,答案只有一个:为了使RxHttp更好用,通过@DefaultDomain
注解,我们可以非常方便的设置baseUrl,这可能是目前对baseUrl最优雅的设置方案(欢迎打脸);通过@Domain
,我们可以非常方便的为单个请求指定非默认的baseUrl;通过@Param
@Parser
注解,我们就可以很方便的在RxHttp使用我们自定义的Param及Parser。 下面将一一介绍。
@DefaultDomain
现实开发中,大部人开发者都会将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 -> {
//失败回调
});
复制代码
RxHttp在发送请求前,会对url做判断,如果没有域名,就会自定加上默认的域名,也就是baseUrl。
@Domain
然后,如果我们不想使用默认的域名呢?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/";
}
复制代码
此时再rebuild一下项目,就会在RxHttp类中生成一个setDomainToUpdate9158IfAbsent()
方法,其中的Update9158
字符就是name
指定的名字,然后发请求就可以这样:
RxHttp.get("/service/getIpInfo.php")
.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!!
@Parser
先来看看源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Parser {
//指定名字后,就会在RxHttp下生成fromXXX方法
String name();
}
复制代码
@Parser
标签作用于Parser
接口的实现类,指定名字后,Rebuild一下项目,就会在RxHttp下生成fromXXX方法。
在RxHttp 一条链发送请求之强大的数据解析功能(二)一文中,我们也自定义了一个DataParser解析器,同时使用了@Parser(name = "DataParser")
注解,我们再次贴上源码
@Parser(name = "DataParser")
public class DataParser<T> extends AbstractParser<T> {
//省略内部代码
}
复制代码
然后Rebuild 一下项目,RxHttp下就会自动生产一个public <T> Observable<T> fromDataParser(Class<T> type)
方法,如:
public class RxHttp {
private Param param;
private RxHttp(Param param) {
this.param = param;
}
//通过注解Parser生成的方法
public <T> Observable<T> fromDataParser(Class<T> type) {
return from(DataParser.get(type));
}
//省略了其它方法
}
复制代码
此时我们就可以直接使用fromDataParser
方法去解析数据了。
String url = "http://ip.taobao.com/service/getIpInfo.php";
RxHttp.postEncryptJson(url) //这里get,代表Get请求
.add("ip", "63.223.108.42")//添加参数
.addHeader("accept", "*/*"); //添加请求头
.fromDataParser(Response.class)
...省略部分代码
复制代码
可见,代码更加的简洁了
注:@Parser
注解只能作用与Parser
的实现类,不能是接口和抽象类,且必须要提供一个静态的get方法,返回该实现类的一个实例对象,编译时会检查
@Param
先来看看@Param
的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Param {
//指定在RxHttp类中生成的静态方法名
String methodName();
}
复制代码
@Param
标签只能作用于AbstractPostParam
的实现类上,否则编译器会报错,指定方法名后,Rebuild一下项目,就会自动在RxHttp类下生成指定方法名的静态方法。
在RxHttp 一条链发送请求之强大的Param类(三)一文中,我们自定义了一个PostEncryptJsonParam
,并为它使用了注解标签@Param(methodName = "postEncryptJson")
我们再次贴上该类的源码
@Param(methodName = "postEncryptJson") //指定postEncryptJson为方法名
public class PostEncryptJsonParam extends AbstractPostParam {
//省略内部代码
}
复制代码
然后Rebuild 一下项目,就可以看到在RxHttp下多了一个postEncryptJson
方法,并在方法内new 出了一个PostEncryptJsonParam
对象传给了RxHttp
public class RxHttp {
private Param param;
private RxHttp(Param param) {
this.param = param;
}
public static RxHttp with(Param param) {
return new RxHttp(param);
}
//通过注解Param生成的方法
public static RxHttp postEncryptJson(String url) {
return with(new PostEncryptJsonParam(url));
}
//省略了其它方法
}
复制代码
接下来,我们就可以直接通过RxHttp发送PostEncryptJsonParam
请求
String url = "http://ip.taobao.com/service/getIpInfo.php";
RxHttp.postEncryptJson(url) //这里get,代表Get请求
.add("ip", "63.223.108.42")//添加参数
.addHeader("accept", "*/*") //添加请求头
//省略部分代码
复制代码
可见@Param
标签,在一定程度上降低了耦合,使我们并不需要关注具体的实现,使用 RxHttp
类即可搞定任意请求
注:@Param
标签只能作用与Param
接口的实现类,该类不能是接口、抽象类,且必须提供一个public 且仅带一个url参数的构造方法,在编译时会做检查。
小结
最后,本文如果有写的不对的地方,请广大读者指出。 如果觉得我写的不错,记得给我点赞RxHttp