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

使用Volley从MySQL获取数据到RecyclerView失败排查求助

Android Volley加载MySQL数据到RecyclerView失败问题排查与修复

在Android中使用Volley通过JSON数组从MySQL获取id为1的所有行数据并加载到RecyclerView时,出现无法将字符串转换为JSON数组的错误,导致数据无法加载。以下是问题排查和修复方案:

一、核心错误点分析

  • PHP语法错误:原PHP代码末尾echo json_encode($all_jobs)缺少分号,会导致PHP解析失败,输出非合法JSON内容。
  • 响应头缺失:未设置Content-Type: application/json,Volley无法正确识别响应类型,增加解析失败概率。
  • SQL注入风险+错误处理缺失:直接拼接$_POST['id']到SQL语句存在注入风险,且未处理数据库连接、查询失败场景,可能输出错误信息破坏JSON格式。
  • Android端未更新适配器:数据添加到集合后未调用适配器的notifyDataSetChanged(),即使加载成功RecyclerView也不会更新。
  • 字符编码问题:PHP输出JSON未指定编码,含非ASCII字符时可能导致解析失败。

二、修复后的代码

1. 修复后的PHP代码

<?php
header("Content-Type: application/json; charset=utf-8"); // 设置响应头与编码
require_once "conn.php";
require_once "validate.php";

// 安全获取POST参数并防注入
$id = isset($_POST['id']) ? mysqli_real_escape_string($conn, $_POST['id']) : '';
if(empty($id)){
    echo json_encode(array("error" => "参数错误"));
    exit;
}

// 使用预处理语句彻底避免SQL注入
$sql = "SELECT * from all_jobs WHERE id = ?";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_bind_param($stmt, "s", $id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

$all_jobs = array();
while($row = mysqli_fetch_assoc($result)){
    $index = array(
        'jobname' => $row['jobname'],
        'posts' => $row['posts'],
        'startdate' => $row['startdate'],
        'enddate' => $row['enddate'],
        'govtfees' => $row['govtfees'],
        'appfees' => $row['appfees'],
        'documents' => $row['documents'],
        'declartion' => $row['declartion'],
        'jobdetails' => $row['jobdetails']
    );
    array_push($all_jobs, $index);
}

// 输出带中文支持的JSON
echo json_encode($all_jobs, JSON_UNESCAPED_UNICODE);
mysqli_stmt_close($stmt);
mysqli_close($conn);
?>

2. 修复后的Android代码

private void LoadAllJobs() {
    StringRequest stringRequest = new StringRequest(Request.Method.POST, Urls.all_jobs,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    try {
                        Log.d("VolleyDebug", "接口返回内容: " + response); // 打印响应便于排查
                        
                        JSONArray jsonArray = new JSONArray(response);
                        allJobs.clear(); // 清空旧数据避免重复加载
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject object = jsonArray.getJSONObject(i);
                            String jobname = object.getString("jobname");
                            String jobdetails = object.getString("jobdetails");
                            String startdate = object.getString("startdate");
                            String enddate = object.getString("enddate");
                            String posts = object.getString("posts");
                            String govtfees = object.getString("govtfees");
                            String appfees = object.getString("appfees");
                            String documents = object.getString("documents");
                            String declartion = object.getString("declartion");

                            AllJobsModel jobModel = new AllJobsModel(
                                    jobname, jobdetails, posts, startdate, enddate,
                                    govtfees, appfees, documents, declartion);
                            allJobs.add(jobModel);
                        }
                        yourRecyclerViewAdapter.notifyDataSetChanged(); // 通知适配器更新
                        AndroidUtil.showToast(getApplicationContext(), "数据加载成功");
                    } catch (JSONException e) {
                        e.printStackTrace();
                        AndroidUtil.showToast(getApplicationContext(), "JSON解析失败: " + e.getMessage());
                        Log.e("JSONError", "解析失败的响应内容: " + response);
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
            AndroidUtil.showToast(getApplicationContext(), "网络请求失败: " + error.getMessage());
        }
    }) {
        @Nullable
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("id", "1");
            return params;
        }
    };

    // 设置超时与重试策略
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(
            5000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    
    RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
    queue.add(stringRequest);
}

三、额外排查建议

  • 直接测试PHP接口:用Postman发送POST请求,查看返回内容是否为标准JSON格式,是否包含错误提示。
  • 查看PHP日志:检查服务器PHP错误日志,确认是否有数据库连接、语法等问题。
  • 检查Android日志:通过Logcat查看Volley返回的原始响应内容,判断是否有多余字符破坏JSON结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:12:22