【问题标题】:Okhttp ignores Dispatcher setting when used with Retrofit RxJavaCallAdapterFactory与 Retrofit RxJavaCallAdapterFactory 一起使用时,Okhttp 会忽略 Dispatcher 设置
【发布时间】:2016-11-27 07:16:19
【问题描述】:

考虑以下 OkHttp 和 Retrofit 的初始化:

public static SomeServiceRestInterface newRestService(String apiUrl) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(apiUrl)
                    .client(createOkHttpClient())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
                    .addConverterFactory(createGsonConverter())
                    .build();
            return retrofit.create(SomeServiceRestInterface.class);
}

private static OkHttpClient createOkHttpClient() {
                    Dispatcher dispatcher = new Dispatcher();
                    dispatcher.setMaxRequestsPerHost(1);
                    dispatcher.setMaxRequests(1);
                    OkHttpClient.Builder builder = new OkHttpClient.Builder()
                                .dispatcher(dispatcher).build()
}

在测试其余调用时,我注意到 Okhttp 根本不支持 setMaxRequestsPerHost 或 setMaxRequests 设置。这是同时发送的 3 个请求的日志:

23/07 04:14:22.668 [RxIoScheduler-4] DEBUG - --> POST https://XXX/1 http/1.1
23/07 04:14:22.668 [RxIoScheduler-4] DEBUG - Content-Length: 0
23/07 04:14:22.668 [RxIoScheduler-4] DEBUG - --> END POST (0-byte body)
23/07 04:14:22.672 [RxIoScheduler-7] DEBUG - --> POST https://XXX/2 http/1.1
23/07 04:14:22.673 [RxIoScheduler-7] DEBUG - Content-Length: 0
23/07 04:14:22.673 [RxIoScheduler-7] DEBUG - --> END POST (0-byte body)
23/07 04:14:22.676 [RxIoScheduler-6] DEBUG - --> POST https://XXX/3 http/1.1
23/07 04:14:22.677 [RxIoScheduler-6] DEBUG - Content-Length: 0
23/07 04:14:22.677 [RxIoScheduler-6] DEBUG - --> END POST (0-byte body)

其中XXX是同一个域,1/2/3是不同的路径。

我不知道为什么,但我认为这可能与 addCallAdapterFactory 中设置的 RxJava 调度程序有关。

这是一个错误吗?还是我错过了什么?

我正在使用 okhttp 3.4.1,并改造 2.1.0。

【问题讨论】:

  • 你检查过你创建了多少个http客户端吗?

标签: android rx-java retrofit2 okhttp3


【解决方案1】:

在这个问题上引用 Jake Wharton 的话:

Observable for Retrofit 的实现执行请求 同步地依赖应用的调度器 限制。如果您需要 OkHttp 的 Dispatcher 的限制 很荣幸,那么您将不得不为 Observable 编写一个自定义 CallAdapter 它使用 Call.enqueue 而不是 Call.execute。

我们目前没有计划支持此功能,但很可能 基于假设的 OkHttp v4 的改造 v3 可能会使其成为 默认(虽然这还很遥远)。

这与使用 Retrofit 调用时看到的行为相同 并调用 .execute(),甚至使用 OkHttp 的 Call 及其 .execute()。

【讨论】:

    【解决方案2】:

    从改造 2.9 开始,RxJavaCallAdapterFactoryRxJava2CallAdapterFactory 的方法 createAsync() 创建使用 Call.enqueue 的 CallAdapter。这会将队列委托给 OkHTTP 的 Dispatcher,因此 maxRequest 设置起作用。

    create()createWithScheduler() 将使用 Call.execute 跳过 Dispatcher

    对于 RxJava3CallAdapterFactory,名称已交换:create() 现在是异步适配器,而之前的直接执行版本已重命名为 createSynchronous()

    【讨论】:

      猜你喜欢
      • 2022-08-19
      • 2015-12-12
      • 2016-01-09
      • 2020-05-15
      • 1970-01-01
      • 2016-06-23
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多