Android API 30下Volley/Retrofit无法访问HTTP的原因排查
问题原因分析与解决办法
核心原因
- 网络安全配置格式不兼容:你的
network_security_config中<domain>标签使用了带端口的IP(xxx.xxx.xxx.xxx:8080),Volley 1.2.1和Retrofit2默认依赖的系统HttpURLConnection无法正确解析这种格式,导致配置的cleartextTrafficPermitted="true"不生效,被API 30的明文流量拦截机制阻止。而OkHttp 4.11.0对带端口的域名配置解析逻辑更完善,能正常识别并允许明文流量。 - API版本限制差异:Android API 27及以下对明文流量的限制执行较宽松,即使配置存在格式问题也能绕过检查;但API 30严格执行网络安全策略,不符合规范的配置直接触发拦截。
- Retrofit2默认客户端局限:Retrofit2 2.9.0默认使用系统
HttpURLConnection而非OkHttp,该组件在API 30下对带端口的IP明文配置支持不足;而你单独使用的OkHttp 4.11.0不受此局限。
解决办法
1. 修正网络安全配置格式
将带端口的IP拆分,只保留IP地址在<domain>标签中,端口无需在配置中指定:
<?xml version="1.0" encoding="utf-8"?> <network-security-config xmlns:android="http://schemas.android.com/apk/res/android"> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">xxx.xxx.xxx.xxx</domain> </domain-config> </network-security-config>
如果需要临时允许所有明文流量(仅测试环境使用,生产环境不建议),可以用<base-config>替代<domain-config>:
<network-security-config xmlns:android="http://schemas.android.com/apk/res/android"> <base-config cleartextTrafficPermitted="true" /> </network-security-config>
2. 给Retrofit2指定OkHttp客户端
添加OkHttp依赖后,修改Retrofit构建逻辑,强制使用OkHttp作为底层客户端:
// 先添加依赖 implementation 'com.squareup.okhttp3:okhttp:4.11.0' // 构建Retrofit实例时指定OkHttpClient OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://xxx.xxx.xxx.xxx:8080/") .client(okHttpClient) .build();
3. 给Volley替换OkHttp作为底层客户端
自定义Volley的HurlStack,让Volley使用OkHttp发送请求:
OkHttpClient okHttpClient = new OkHttpClient(); RequestQueue requestQueue = Volley.newRequestQueue(context, new HurlStack() { @Override protected HttpURLConnection createConnection(URL url) throws IOException { return okHttpClient.newCall(new Request.Builder().url(url).build()).request().url().openConnection(); } });
内容的提问来源于stack exchange,提问作者user23335744
相关产品推荐
相关产品推荐

