Scenario:
Restarting the app with internet enabled from start will make everything work, unless I close it again, and fail a request, from that point on it will give me the same error. I never had this issue on Java, just on Kotlin.
private val interceptor: Interceptor =
object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var builder = chain.request().newBuilder()
Prefs.token?.let { token ->
builder = builder.addHeader("Authorization", "Bearer $token")
}
return chain.proceed(builder.build())
}
}
private val httpLoggingInterceptor: HttpLoggingInterceptor by lazy {
val interceptor = HttpLoggingInterceptor()
interceptor.level =
if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
interceptor
}
private val httpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(interceptor)
.build()
}
val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl("https://api.secret.com/v1/")
.addConverterFactory(GsonConverterFactory.create(gson))
.client(httpClient)
.build()
}
And the service classes look like this
@GET("something")
fun something(): Call<SomeResponse>
I've tried playing around with timeout values, no matter the timeout time, I will get the same error.
Creating a new http client for every request will fix the issue, but I don't think is a good idea.
Your issue looks like OkHttp Bug. If you follow the link, you will find long discussion with many possible solutions.
okHttpClientBuilder.pingInterval(1, TimeUnit.SECONDS)
The root of the issue is that Android OS doesn't provide any way to know that connection isn't active any more. So that for library connection looks like alive, but it's already dead. As a result we get timeout exception on every request. Once we set ping, OkHttp starts sending Ping frames, so that if server doesn't respond library knows that connection is already dead, and it's time to create a new one.
okHttpClientBuilder.connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
okHttpClientBuilder.protocols(listOf(Protocol.HTTP_1_1))
In both not recommended solutions you just stop reusing already opened connection that makes each request time little bit longer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With