【问题标题】:Why does creating an instance of OkHttpClient take so long?为什么创建 OkHttpClient 的实例需要这么长时间?
【发布时间】:2019-04-13 20:16:34
【问题描述】:

我在 Android 2.3 Gingerbread 设备上获得了此代码,大约需要 30 秒。

我在远离 UI 线程的异步任务中运行它(但我在哪里运行它并没有什么不同)

long startTime = System.nanoTime();
OkHttpClient client = new OkHttpClient.Builder()
        .followRedirects(false)
        .build();
long clientBuilt = System.nanoTime();
Log.d("API", String.format("Created OkHttpClient, it took %f milliseconds", (clientBuilt - startTime)/1000000d));
D/API: Created OkHttpClient, it took 30814.207720 milliseconds

我有这个 Android 版本的最新版本的 OkHttp: 'com.squareup.okhttp3:okhttp:3.12.0'

编辑:

应用 Martin 建议的代码后: .connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT))

并运行对服务器的调用我得到一个异常:

java.io.IOException: unexpected end of stream on Connection{motoactv.com:443, proxy=DIRECT hostAddress=motoactv.com/69.10.180.44:443 cipherSuite=none protocol=http/1.1}
        at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:208)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        ...
Caused by: java.io.EOFException: \n not found: limit=0 content=…
        at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:236)
        at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215)
        at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) 
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)

【问题讨论】:

  • 我怀疑您的设备有问题。我将您的代码放入一个废弃项目中,它在现代硬件上运行大约 0.3 秒。但是,与 Android 2.3 设备应该没有 1000 倍的差异。
  • @Kamil 你在代理后面吗?如果是这样,请检查:stackoverflow.com/questions/37866902/okhttp-proxy-settings
  • @madlymad 不幸的是,这里没有代理

标签: java android okhttp3 android-2.3-gingerbread


【解决方案1】:

这么老的API还不支持SNI;强制执行纯文本 HTTP 可能会有所帮助:

OkHttpClient client = new OkHttpClient.Builder()
    .connectionSpecs(Arrays.asList(ConnectionSpec.CLEARTEXT))
    .followRedirects(false)
    .build();

走进OkHttpClient.Builder 也应该知道它到底卡在哪里了。

【讨论】:

  • 3.12中没有ConnectionSpec.NONE,只有:CLEARTEXTCOMPATIBLE_TLSMODERN_TLSRESTRICTED_TLS
  • @Kamil 我的意思是CLEARTEXT... 如果没有SNI 支持,大多数当前证书甚至会被拒绝,因此即使尝试使用它也没有用。使用 Fernflower 进行反编译将允许进入 - 就像将其添加为本地库模块一样可以进行更仔细的检查。
  • 试一试,仅供参考,connectionSpecs() 将列表作为参数
  • @Kamil 我已经解决了。
  • 我刚刚编辑了我的问题,以包括在应用您的代码并运行对服务器的调用后得到的异常。实际上,客户端的创建速度要快得多,例如毫秒,但随后调用失败
猜你喜欢
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多