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,需要修改导入的类:
大部分API逻辑和2.x差不多,你的现有代码只需要替换包名就能正常运行,比如RequestBody的创建方式完全一致。// 替换原来的okhttp包导入 import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.OkHttpClient;
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




