You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

API25及以上版本连接REST Service时遇IOException求助

排查REST API读取IOException问题(API25+)

我之前帮同事排查过几乎一模一样的问题,结合你描述的conn.getInputStream()抛异常、isConnected返回false的情况,咱们从代码逻辑、系统配置和网络环境三个维度来拆解:

一、先排查代码层面的常见坑

1. 绝对不能在主线程发起网络请求

API25之后Android严格禁止在主线程执行网络操作,哪怕你没直接看到NetworkOnMainThreadException,也可能间接触发IOException(因为主线程网络请求会被系统强制中断)。

解决办法:把请求放到子线程,比如用AsyncTask(API25完全可用)、Coroutine或者RxJava:

// 示例:用AsyncTask做网络请求
new AsyncTask<Void, Void, String>() {
    @Override
    protected String doInBackground(Void... voids) {
        String result = "";
        try {
            URL url = new URL("你的API地址");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            
            // 先打印响应码,排查服务器端问题
            int responseCode = conn.getResponseCode();
            Log.d("API_DEBUG", "响应码: " + responseCode);
            
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = conn.getInputStream();
                result = new Scanner(inputStream, "UTF-8").useDelimiter("\\A").next();
                inputStream.close();
            } else {
                // 读取错误流,获取服务器返回的错误信息
                InputStream errorStream = conn.getErrorStream();
                String errorMsg = new Scanner(errorStream, "UTF-8").useDelimiter("\\A").next();
                Log.e("API_ERROR", "错误信息: " + errorMsg);
            }
            conn.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        Log.d("JSON_RESULT", s);
    }
}.execute();

2. 检查连接配置是否完整

  • 确认请求方法是否正确(比如API要求POST,你用了GET)
  • 设置合理的超时时间(避免因超时触发IOException)
  • 如果API需要请求头(比如Content-Type、Authorization),一定要加上:
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", "Bearer 你的token");

3. 优先用getResponseCode()排查问题

不要直接抓getInputStream()的异常,先调用conn.getResponseCode():

  • 如果返回4xx/5xx,说明服务器端有问题,用conn.getErrorStream()读取错误详情
  • 如果返回200再去读输入流,能帮你快速定位是网络问题还是服务器问题

二、系统配置必须到位(API25+的特殊要求)

1. 网络权限不能少

在AndroidManifest.xml里必须添加:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

INTERNET是正常权限,不需要动态申请;ACCESS_NETWORK_STATE用来判断设备是否真的联网。

2. 明文HTTP请求的限制(API28+默认禁止)

如果你的API是HTTP协议(不是HTTPS),API28之后默认会拦截明文请求,触发IOException。解决办法:

  • 在res/xml下创建network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- 允许所有明文请求(测试用,上线建议只允许指定域名) -->
    <base-config cleartextTrafficPermitted="true"/>
    <!-- 或者只允许特定域名的明文请求 -->
    <!--
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">your-api-domain.com</domain>
    </domain-config>
    -->
</network-security-config>
  • 在AndroidManifest.xml的application标签里引用:
<application
    ...
    android:networkSecurityConfig="@xml/network_security_config">

3. HTTPS证书问题(如果API是HTTPS)

如果API用的是自签名证书或者无效证书,会触发SSLHandshakeException(属于IOException的子类)。需要在代码里配置信任该证书,或者让服务器更换有效证书。

三、网络环境排查(你怀疑的防火墙问题)

1. 先确认设备真的联网

用代码判断当前网络状态:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
Log.d("NETWORK_CHECK", "设备是否联网: " + isConnected);

如果这里返回false,说明设备本身没联网,和API无关。

2. 排除防火墙/代理干扰

  • 切换网络:比如从公司WiFi换成手机流量,测试是否能连接API
  • 用ping命令测试API域名:在电脑终端执行ping your-api-domain.com,看是否能通
  • 检查设备是否设置了代理:如果有代理,可能导致无法连接API

最后总结排查步骤

  1. 先用Postman/浏览器访问API,确认API本身能正常返回JSON
  2. 把网络请求移到子线程,避免主线程限制
  3. 检查Manifest权限和网络安全配置
  4. 打印响应码和错误流,定位具体异常原因
  5. 切换网络测试,排除防火墙/代理问题

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:30:01