策略系统 - GateOfTruth/OkSimple GitHub Wiki
策略系统是我从2.0.0版本开始,给oksimple新增的一个功能。在介绍什么是策略系统之前,我觉得有必要先介绍为什么要写这个系统。因为只有知道了原因,才能更好的理解和使用。我将通过以下三个场景来解释创造策略系统的初衷。
现在有一个get/post请求,你必须保证这个请求要成功和服务器产生交互。但是实际情况很复杂,有些时候可能因为网络波动等原因,没能成功请求。这个时候你必须捕获这次失败的请求,并重新发起它,直到成功。简称至少成功一次。
现在有一个get/post请求,你必须保证这个请求无论成功失败,都是每X秒请求一次服务器。这个请求可能是存在于某个activity/fragment,或者存在于整个app的生命周期里。简称为轮询请求。
你的公司买了阿里云的服务器,又买了腾讯云的服务器。因此有了多个域名。阿里云的域名是首选域名,腾讯云的是备选域名,当阿里云因为一些原因无法访问的时候,我们客户端要手动切换到腾讯云的域名(别问这件事为什么要客户端做,有些时候就是这样)。当然,不仅是域名,甚至还要动态修改header等。
现在你可以思考一下如果是用你现有的网络请求框架,你会怎么做?
不管是轮询还是至少成功一次,或者动态修改host,header等,本质都是对当前已经发出的请求的一种重复,只是重复的方式和想要得到的结果不同。因此就有了目前这个策略系统。在oksimple里,所有的请求都被抽象成了策略,你每一次请求,其实是发起一次策略。每个请求的策略都可以是不同的或者相同的。不仅如此,策略系统不同于很多框架常见的超时重试机制,它可以针对exception,response code,服务器返回code等任何你能从okhttp获取的信息进行策略的配置,基本能满足所有的场景与需求。
oksimple里使用RequestStrategy作为所有请求的抽象类
abstract class RequestStrategy {
open var strategyResultCallBack: ResultCallBack? = null
open var strategyCall: Call? = null
open var count = 0L
/**
* 返回response时候是否继续请求
*/
abstract fun requestAgainOnResponse(call: Call, response: Response): Boolean
/**
* 是否调用ResultCallBack的Response方法
*/
abstract fun callBackResponse(call: Call, response: Response): Boolean
/**
* 是否调用ResultCallBack的Failure方法
*/
abstract fun callBackFailure(call: Call, e: IOException): Boolean
/**
* 失败时候的是否请求
*/
abstract fun requestAgainOnFailure(call: Call, e: IOException): Boolean
/**
*重写url或者header用
*/
abstract fun getRequestBuilder(builder: Request.Builder): Request.Builder
/**
* 延迟时间毫秒数
*/
abstract fun requestDelay(): Long
/**
* 最大请求次数
*/
abstract fun maxRequestTimes(): Long
/**
* 是否调用ResultCallBack里的start方法
*/
abstract fun callBackStart(): Boolean
}
虽然看上去方法很多,但是我会用非常简单的伪代码进行说明
if (strategy.callStartFunction()) {
callBack?.start()
}
strategy.count++
client.newCall(strategy.getRequestBuilder(requestBuilder).build())
.enqueue((object : Callback {
override fun onFailure(call: Call, e: IOException) {
if (strategy.doResultCallBackFailure(call, e)) {
callBack?.failure(call, e)
}
if (strategy.doRequestWhenOnFailure(call, e)) {
//根据策略重新发起请求
}
}
override fun onResponse(call: Call, response: Response) {
if (strategy.doResultCallBackResponse(call, response)) {
callBack?.response(call, response)
}
if (strategy.doRequestWhenOnResponse(call, response)) {
//根据策略重新发起请求
}
}
}))
callback相关的请参考 ResultCallBack。
oksimple内置了两个策略DefaultStrategy和RequestUntilSuccess,以及demo里的ChangeHostStrategy,写其他策略的时候可以参考这几个,基本上目前自己的项目中所有的情况都能覆盖到。通常来说,一个普通的请求是不用设置策略的,每个请求都会使用DefaultStrategy作为默认的策略。
使用的时候也很简单,
OkSimple.get(url).setRequestStrategy(Strategy)
这样,这个请求的策略就设置好了,如果你不设置的话,这个请求就会和以前一样,无论成功失败都只是正常的请求一次。