You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 8.0中使用OkHttp 2.7.5读取响应抛出异常(7.x正常)

解决Android 8.0下OkHttp 2.7.5 SSL读取异常问题

嘿,这个问题我之前碰到过类似的,核心原因是Android 8.0(API 26)开始系统默认改用Conscrypt作为SSL/TLS的底层实现,而你用的OkHttp 2.7.5是2016年的老版本,完全没适配这个新的SSL框架,所以在读取响应时触发了Native层的SSL_read异常,而Android 7.x用的还是旧的AndroidOpenSSL,所以运行正常。

下面给你几个可行的解决方案,按优先级排序:

1. 优先升级OkHttp版本(最推荐)

OkHttp 2.x系列已经停止维护多年,官方早就不再更新了,升级到3.x及以上版本可以彻底解决这个兼容性问题,同时还能获得更多安全补丁和功能。

  • 替换依赖:把原来的compileOnly依赖改成OkHttp3的稳定版本(比如3.12.x,这个版本兼容Android 4.0+,适合需要兼容老系统的项目):
    implementation 'com.squareup.okhttp3:okhttp:3.12.13'
    
  • 代码适配:因为OkHttp3的包名变成了okhttp3,需要修改导入的类:
    // 替换原来的okhttp包导入
    import okhttp3.Request;
    import okhttp3.RequestBody;
    import okhttp3.Response;
    import okhttp3.OkHttpClient;
    
    大部分API逻辑和2.x差不多,你的现有代码只需要替换包名就能正常运行,比如RequestBody的创建方式完全一致。

2. 不升级OkHttp的情况下,手动指定SSL实现

如果因为项目限制无法升级OkHttp,可以给OkHttpClient强制设置旧的AndroidOpenSSL作为SSL提供者,绕开Conscrypt:

try {
    // 初始化旧的SSLContext
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, null, new SecureRandom());
    SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

    // 配置到你的httpClient
    httpClient.setSslSocketFactory(sslSocketFactory);
    // 保持默认的主机名验证,避免证书信任问题
    httpClient.setHostnameVerifier(HostnameVerifier.DEFAULT);
} catch (NoSuchAlgorithmException | KeyManagementException e) {
    e.printStackTrace();
}

⚠️ 注意:这种方式会降低一定的安全性,因为绕过了系统默认的安全SSL实现,只建议作为临时过渡方案。

3. 检查服务器端SSL配置

有时候问题出在服务器端:Android 8.0的Conscrypt默认禁用了一些老旧的加密套件和TLS版本(比如TLS 1.0),如果你的服务器只支持这些不安全的配置,也会导致握手或读取异常。

可以用SSL测试工具检查服务器的SSL配置,确保服务器支持TLS 1.2及以上版本,并且包含Conscrypt兼容的加密套件(比如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256这类)。


内容的提问来源于stack exchange,提问作者Prabhakaran

火山引擎 最新活动