前言
当APP中有发起大量服务端接口调用请求时,或许有人希望能够指定某些请求任务的优先级较高,可以优先发起请求。或者指定其为低优先级,在靠后的位置再发起请求。那么如果可以给这些请求设置优先级,使之能够按优先级顺序执行的话就很方便了。
不过遗憾的是,OkHttp库不支持开发者给Request设置优先级。若要支持按优先级调度,则需要业务方自行维护请求任务队列,然后通过Call#execute方法依次执行请求任务,但该方案的弊端是不能利用OkHttp原有的请求队列管理,且对业务方具有侵入性。或者通过给Dispatcher设置自定义的ExecutorService,队列使用PriorityBlockingQueue,但该方式仅在执行任务且核心线程数满的情况下,任务进入PriorityBlockingQueue才能达到优先级调度的目的,且同样具有侵入性。
能否让开发者在利用OkHttp原有请求队列管理且不需要额外扩展自定义配置的基础上,只需要一行代码就可以给请求设置优先级呢?可以借助OkOne库来实现。
如何设置
首先集成OkOne库,集成步骤详见 https://github.com/chidehang/OkOne 。
集成后便可只用一行代码就能够设置请求优先级:
// 创建请求Request
Request request = Request.Builder().url(api).build();
// 给Request设置一个优先级
OkOne.setRequestPriority(request, priority);
有一点需要说明的是:Call#enqueue发起请求任务,若OkHttp内部的请求中队列(runningAsyncCalls)未达到最大并发数限制,则该任务会立即执行,否则任务会暂时在等待队列(readyAsyncCalls)中等待调度执行。因此优先级只对排队待执行的任务有意义。
效果演示
- 创建多个Request,并随机设置优先级
val N = 10
val requests = arrayOfNulls<Request>(N)
val r = Random(System.currentTimeMillis())
for (i in 0 until N) {
// 随机生成请求优先级
val priority = r.nextInt(20) - 10
// 打印日志
LogUtils.d(TAG, "$i => $priority")
requests[i] = Request.Builder()
.url(api)
// TagEntity记录创建顺序和优先级,仅用于后续打印信息
<