策略系统 - GateOfTruth/OkSimple GitHub Wiki

为什么?

策略系统是我从2.0.0版本开始,给oksimple新增的一个功能。在介绍什么是策略系统之前,我觉得有必要先介绍为什么要写这个系统。因为只有知道了原因,才能更好的理解和使用。我将通过以下三个场景来解释创造策略系统的初衷。

场景A

现在有一个get/post请求,你必须保证这个请求要成功和服务器产生交互。但是实际情况很复杂,有些时候可能因为网络波动等原因,没能成功请求。这个时候你必须捕获这次失败的请求,并重新发起它,直到成功。简称至少成功一次。

场景B

现在有一个get/post请求,你必须保证这个请求无论成功失败,都是每X秒请求一次服务器。这个请求可能是存在于某个activity/fragment,或者存在于整个app的生命周期里。简称为轮询请求。

场景C

你的公司买了阿里云的服务器,又买了腾讯云的服务器。因此有了多个域名。阿里云的域名是首选域名,腾讯云的是备选域名,当阿里云因为一些原因无法访问的时候,我们客户端要手动切换到腾讯云的域名(别问这件事为什么要客户端做,有些时候就是这样)。当然,不仅是域名,甚至还要动态修改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内置了两个策略DefaultStrategyRequestUntilSuccess,以及demo里的ChangeHostStrategy,写其他策略的时候可以参考这几个,基本上目前自己的项目中所有的情况都能覆盖到。

使用的时候也很简单,

   
OkSimple.get(url).setRequestStrategy(Strategy)

这样,这个请求的策略就设置好了,如果你不设置的话,这个请求就会和以前一样,无论成功失败都只是正常的请求一次。
⚠️⚠️⚠️需要注意的是,请妥善管理你的策略,诸如轮询请求等长期存在于后台的策略,请在destory里销毁,否则可能造成内存泄漏。销毁的方法请参考取消请求

⚠️ **GitHub.com Fallback** ⚠️