协程请求三部曲代码表示
//协程,获取接口返回数据,以String类型返回
val str = RxHttp.get("/service/…") //1、确定请求方式,可选get、postXxx等方法
.toStr() //2、使用toXxx系列方法确定返回类型
.await() //3、使用await方法拿到返回值
协程请求三部曲详解
-
第一步,选择
get、postForm、postJson
等方法来确定请求方式,随后便可通过add、addFile、addHeader/
操作符来添加参数、文件、请求头
,当然,我们还可以调用更多的操作符来满足业务需求,如setCacheXxx、upload
等来设置缓存策略及监听上传进度等等 -
第二步,调用
toXxx
系列方法来确定返回类型,常用的有toStr、toClass、toList
,随后便可调用asFlow、retry、timeout、flowOn、filter、distinct、sort
等30余个操作符来执行不同的业务逻辑,本文后续会一一介绍 -
第三步,最后,只需调用
await、tryAwait、awaitResult
这三个中的任一操作符获取返回值即可,这一步,需要在协程环境中才能调用
如:我们要发送一个post
表单请求,参数/文件/请求头各添加一个,并将返回数据反序列化为Student
对象,其中超时时间设置为5秒;失败重试2次,每次间隔1秒,代码如下:
val student = RxHttp
.postForm("/service/…") //1、确定请求方式,可以选择get、postXxx等方法
.add(“key”, “value”)
.addFile(“file”, File("…/1.png"))
.addHeader(“headerKey”, “headerValue”)
.toClass() //2、使用toXxx系列方法确定返回类型
.timeout(5000)
.retry(2, 1000)
.await() //3、使用await方法拿到返回值
2.2、BaseUrl处理
RxHttp通过@DefaultDomain、@Domain
注解来配置默认域名及非默认域名,如下:
public class Url {
@DefaultDomain //通过该注解设置默认域名
public static String BASE_URL = “https://www.wanandroid.com”;
// name 参数在这会生成 setDomainToGoogleIfAbsent方法,可随意指定名称
// className 参数在这会生成RxGoogleHttp类,可随意指定名称
@Domain(name = “Google”, className = “Google”)
public static String GOOGLE = “https://www.google.com”;
}
以上配置www.wanandroid.com
为默认域名,www.google.com
为非默认域名
多BaseUrl处理
//使用默认域名发请求
RxHttp.get("/service/…")
.toSrt().await()
//使用google域名方式一:传入的url直接带上google域名
RxHttp.get(“https://wwww.google.com/service/…”)
.toSrt().await()
//使用google域名方式二:调用setDomainToGoogleIfAbsent方法
RxHttp.get("/service/…")
.setDomainToGoogleIfAbsent()
.toSrt().await()
//使用google域名方式三:直接使用RxGoogleHttp类发送请求
RxGoogleHttp.get("/service/…")
.toSrt().await()
注意:手动传入的域名优先级别最高,其次是调用setDomainToXxx方法,最后才会使用默认域名
动态域名处理
//直接对url重新赋值即可,改完立即生效
Url.BASE_URL = “https://www.baidu.com”;
RxHttp.get("/service/…")
.toSrt().await()
//此时请求的url为 https://www.baidu.com/service/…
2.3、业务code统一判断
我想大部分人的接口返回格式都是这样的
class Response {
var code = 0
var msg : String? = null
var data : T
}
拿到该对象的第一步就是对code做判断,如果code != 200
(假设200代表数据正确),就会拿到msg字段给用户一些错误提示,如果等于200,就拿到data字段去更新UI,常规的写法是这样的
val response = RxHttp.get("/service/…")
.toClass<Response>()
.await()
if (response.code == 200) {
//拿到data字段(Student)刷新UI
} else {
//拿到msg字段给出错误提示
}
试想一下,一个项目少说也有十几个这样的接口,如果每个接口读取这么判断,就显得不够优雅,也可以说是灾难,相信也没有人会这么干
。而且对于UI来说,只需要data字段即可,错误提示啥的我管不着。
那有没有什么办法,能直接拿到data字段,并且对code做出统一判断呢?有的,直接上代码
val student = RxHttp.get("/service/…")
.toResponse() //调用此方法,直接拿到data字段,也就是Student对象
.await()
//直接开始更新UI
可以看到,这里调用了toResponse()
方法,就直接拿到了data字段,也就是Student对象。
此时,相信很多人会有疑问,
-
业务code哪里判断的?
-
业务code非200时,msg字段怎么拿到?
为此&#