简体   繁体   中英

OkHttp3 cannot start handshake on Android

I make a simple request just to check if I have Internet access:

return try {
    val request = Request.Builder()
        .url("https://www.google.com")
        .build()

    val response = OkHttpClient()
        .newCall(request)
        .execute()

    response.body()?.close()
    response.isSuccessful
} catch (e: IOException) {
    false
}

And pretty often I fall into catch block with java.net.SocketTimeoutException: Read timed out . I found out that OkHttp doesn't go further this line in okhttp3.internal.connection.RealConnection :

private void connectTls(ConnectionSpecSelector connectionSpecSelector) throws IOException {
    // ...
    try {
        // ...
        sslSocket.startHandshake(); // never goes to the next line
        // ...
    } catch(AssertionError e) {
    // never goes here
    } finally {
    // goes here
    }
}

I can't figure out what happens in sslSocket.startHandshake() because apparently sslSocket is com.android.org.conscrypt.ConscryptEngineSocket and Android doesn't really want me to see how it works. Is it some kind of a bug or I just do something wrong? Is there a fix or at least a workaround?

Log:

Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setUseSessionTickets(Z)V (blacklist,core-platform-api, reflection, denied)
Accessing hidden method Lcom/android/org/conscrypt/ConscryptEngineSocket;->setHostname(Ljava/lang/String;)V (blacklist,core-platform-api, reflection, denied)

I use Android 11 (API 30) and OkHttp3 v3.12.0.

PS As I remember, I can't update OkHttp to something newer because I have another dependencies that rely on OkHttp of this particular version because newer versions are backward incompatible.

Seems like your okhttp3 library version access any internal restricted (by new android versions) classes by reflection.

Here is described how to conform and how to find the maximal suitable solution for you: https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces

or...

An quick workaround is to decrease "android build tools" version to a version where such restrictions are not implemented yet. Is a small hack to avoid restrictions on new android versions. But be careful because playmarket will not accept an application compiled with a too old "build tools", so it is not a durable solution.

Upgrade to OkHttp3 v3.12.12, this was fixed already.

See https://square.github.io/okhttp/changelog_3x/#version-3129

migrating to OkHttp3 4.4.0 has fixed the issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM