android - 继续获取 java.io.InterruptedIOException : timeout in Retrofit2

标签 android https timeout retrofit2 timeoutexception

我在办公室很少遇到 java.io.InterruptedIOException: timeout

但是,它在商店中不断发生。

所以,我设置

client.addInterceptor(httpLoggingInterceptor)
            .connectTimeout(5, TimeUnit.SECONDS)
            .callTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)

但是,这没有用。

那么,我在 .enqueue() 中做了什么

fun startPay(){
    // ... Service Generator and so on...
    override fun onFailure(call: Call<ResultData>, t: Throwable) {
        when(t){
            is InterruptedIOException ->{
                Thread.sleep(1000)
                startPay()
            }
            else->{
                Toast.makeText(this, t.toString(), Toast.LENGTH_SHORT).show()
            }
        }
    }
}

我猜这是因为在短时间内点击了两次以上,或者我在 200 次响应后连续调用了 3 次。前任。 A 调用 -> 200 响应 -> B 调用 -> 200 响应 -> C 调用 -> 200 响应 -> UI 更新。 现在,它捕获异常并重试 api 调用。我认为这没有理由被同一个线程或其他线程中断..

这个解决方案总体上很好。但问题是当我付钱时它必须只调用一次。

这个 InterrupedIOException: timeout(不是 SocketTimeout)似乎在从服务器获得响应之前取消了连接,服务器正在很好地发送响应并且没有问题。

stackoverflow的一些问题提到了Crashlystics。我正在使用它,但我不应该将其删除。

我正在使用:

    // Firebase
    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:26.0.0')
    implementation 'com.google.firebase:firebase-core'
    implementation 'com.google.firebase:firebase-auth'
    implementation 'com.google.firebase:firebase-auth-ktx'
    implementation 'com.google.firebase:firebase-config' // remote config
    implementation 'com.google.firebase:firebase-analytics'
    implementation 'com.google.firebase:firebase-analytics-ktx'
    implementation 'com.google.firebase:firebase-crashlytics'
    implementation 'com.google.firebase:firebase-perf'
    implementation 'com.google.firebase:firebase-config-ktx'

    // Network
    // okhttp: https://github.com/square/okhttp
    implementation 'com.squareup.okhttp3:okhttp:4.7.2'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.7.2'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
    implementation 'org.conscrypt:conscrypt-android:2.2.1' // optional

错误在这里:

java.io.InterruptedIOException: timeout
W/System.err: java.io.InterruptedIOException: timeout
W/System.err:     at okhttp3.internal.connection.RealCall.timeoutExit(RealCall.kt:384)
W/System.err:     at okhttp3.internal.connection.RealCall.maybeReleaseConnection(RealCall.kt:346)
W/System.err:     at okhttp3.internal.connection.RealCall.noMoreExchanges$okhttp(RealCall.kt:310)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:205)
W/System.err:     at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:502)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
W/System.err:     at java.lang.Thread.run(Thread.java:761)
W/System.err: Caused by: java.io.IOException: Canceled
W/System.err:     at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:72)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at com.example.helper.api.ServiceGenerator$createService$$inlined$-addInterceptor$1.intercept(Interceptor.kt:87)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)
W/System.err:     at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:197)
W/System.err:   ... 4 more

最佳答案

其中一个可能的原因是 okhttp3 中的一个错误。设置超时后,POST 请求可能会在 IPv6 网络下被取消,并显示如前所述的日志。我可以使用 IPv6Droid 应用程序重现它进行测试(它不是免费的)。

要修复它,只需删除 .callTimeout()

关于android - 继续获取 java.io.InterruptedIOException : timeout in Retrofit2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65733341/

相关文章:

android - MediaPlayer 在 Android 上启动和停止

android - flutter 运行命令不会在 iOS 模拟器中启动

Android组合查询

python - 通过 HTTPS 使用 gevent/grequests 的奇怪阻塞行为

java - 如何在没有证书身份验证或主机名验证的情况下使用 Java 中的 HttpClient 发出 HTTPS 请求?

database - 数据库连接超时模拟

android - 升级到 Android Studio 2.3 后出现 "package android.support.multidex does not exist"

c# - 如何强制相对 URI 使用 https?

c# - WCF:套接字连接已中止。远程主机超过接收超时

php - Heroku - cURL 超时 (PHP)