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

Android Volley请求频繁抛NoConnection/EOFException及JSON解析异常求助

看起来你在使用Volley的StringRequest发起POST请求时遇到了一堆头疼的问题——频繁的连接异常偶尔才能拿到数据,还有JSON解析报错。我来帮你一步步排查这些问题:

一、先解决网络连接类异常(NoConnection Error、EOFException)

这些异常通常和请求的基础配置、网络环境或者服务器端的要求有关,你可以按下面的步骤排查:

  • 检查请求端点的有效性
    首先确认UrlEndPoints.interAd这个URL是完全正确的,包括协议(http/https)、域名和路径。如果你的应用是Android 9及以上版本,默认是禁止HTTP明文请求的,要是后端用的是HTTP,你需要在AndroidManifest.xml的<application>标签里添加:

    android:usesCleartextTraffic="true"
    

    或者配置更安全的network_security_config.xml来允许特定域名的明文请求。

  • 验证请求参数的正确性
    在getParams()方法里添加日志,确认你传递的参数是否符合后端的要求:

    @Override
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<>();
        params.put("task", "get_interad_apps");
        String packageName = getPackageName();
        params.put("package", packageName);
        // 打印参数确认
        Log.d("VolleyParams", params.toString());
        return params;
    }
    

    重点确认:后端是否期望package这个字段名?会不会是package_name或者其他名称?另外getPackageName()返回的包名是否正确?

  • 检查Volley的请求头配置
    StringRequest默认的Content-Type是application/x-www-form-urlencoded,如果后端要求的是application/json,那用getParams()传递参数是无效的,这时候需要重写getBody()和getHeaders():

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        return headers;
    }
    
    @Override
    public byte[] getBody() throws AuthFailureError {
        try {
            JSONObject params = new JSONObject();
            params.put("task", "get_interad_apps");
            params.put("package", getPackageName());
            return params.toString().getBytes("utf-8");
        } catch (Exception e) {
            return null;
        }
    }
    
  • 排查服务器端和网络环境
    试试用Postman或者curl直接调用这个接口,看看能不能正常返回数据。如果Postman也有问题,那大概率是后端的问题(比如接口限流、服务器不稳定)。另外换个网络环境测试(比如从WiFi换成手机流量),排除代理或者网络波动的影响。

二、解决JSON解析异常

JSON解析报错通常是因为返回的响应格式不符合预期,或者你的解析逻辑有问题:

  • 先确认响应的真实内容
    在onResponse的最开头,把完整的response打印出来,看看是不是有效的JSON:

    @Override
    public void onResponse(String response) {
        Log.d("FullResponse", "Raw response: " + response);
        // 后续的解析逻辑...
    }
    

    很多时候出现解析异常,是因为后端返回的不是JSON,而是HTML错误页面(比如404、500错误),或者返回的JSON格式有语法错误(比如多余的逗号、引号不匹配)。

  • 优化JSON解析逻辑,增加容错性
    不要直接用getInt()、getString()这些方法,改用optInt()、optString()来避免字段不存在或者为空时抛出异常,同时检查JSON结构是否符合预期:

    try {
        JSONObject jsonObject = new JSONObject(response);
        Log.e("jObj_AppURL", jsonObject.toString());
        // 用optInt,指定默认值
        int success = jsonObject.optInt(SUCCESS, 0);
        if (success == 1) {
            // 先判断是否存在RESPONSE数组,避免空指针
            JSONArray data = jsonObject.optJSONArray(RESPONSE);
            if (data != null && data.length() > 0) {
                for (int i = 0; i < data.length(); i++) {
                    JSONObject c = data.optJSONObject(i);
                    if (c != null) {
                        // 用optString,空值时返回空字符串
                        appImg = c.optString(APPIMG, "");
                        appName = c.optString(APPNAME, "");
                        appPackages = c.optString(PKG, "");
                        InterAdModel interAdModel = new InterAdModel();
                        interAdModel.setAppImg(appImg);
                        interAdModel.setAppName(appName);
                        interAdModel.setAppPackages(appPackages);
                        interAdModelArrayList.add(interAdModel);
                    }
                }
            }
        }
    } catch (JSONException e) {
        Log.e("JSONParseError", "解析失败: " + e.getMessage());
        e.printStackTrace();
    }
    

    另外要确认SUCCESS、RESPONSE、APPIMG这些常量的字符串值,和后端返回的JSON字段名完全一致(包括大小写),比如后端返回的是"success"而你定义的SUCCESS是"SUCCESS",就会导致解析失败。

额外的调试建议

  • 在onErrorResponse里打印更详细的错误信息,比如:
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e("VolleyError", "错误详情: ", error);
        if (error.networkResponse != null) {
            Log.e("Status Code", String.valueOf(error.networkResponse.statusCode));
            String errorBody = new String(error.networkResponse.data);
            Log.e("Error Body", errorBody);
        }
        Toast.makeText(SplashActivity.this, "请求失败: " + error.getMessage(), Toast.LENGTH_LONG).show();
    }
    
    这样能看到服务器返回的状态码和错误响应体,更容易定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:19:53