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

音乐App中JSON解析数据无法写入POJO类的问题求助

问题分析与解决方案

我帮你看了下代码,核心问题是数据更新没有同步到RecyclerView适配器,加上列表引用的处理不当,导致适配器始终持有空列表,所以显示为空。咱们一步步来解决:

1. 修正列表引用与数据填充逻辑

你在doInBackground里重新创建了onlinePojos的新实例,但适配器初始化时持有的是原来的空列表引用,两者指向不同的对象,所以新数据根本没传到适配器里。

修改后的AsyncTask部分:

class onlinesongdisplay extends AsyncTask<Void, Void, String> {
    json js = new json();
    @Override
    protected void onPreExecute() { super.onPreExecute(); }
    @Override
    protected String doInBackground(Void... urls) {
        js = new json();
        String result = js.processdata(url);
        // 不要重新new列表,而是清空原有列表(确保和适配器持有的是同一个引用)
        onlinePojos.clear();
        try {
            JSONObject jo = new JSONObject(result);
            JSONArray ja = jo.getJSONArray("res");
            for (int i = 0; i < ja.length(); i++) {
                JSONObject j = ja.getJSONObject(i);
                // 用局部变量创建POJO,避免线程安全问题
                OnlinePojo onlinePojo = new OnlinePojo();
                onlinePojo.setSongname(j.getString("songname"));
                onlinePojo.setAlbum(j.getString("albumname"));
                // 补充其他字段的赋值(根据后端返回的JSON键名调整)
                onlinePojo.setArtist(j.getString("artist"));
                onlinePojo.setId(j.getString("id"));
                onlinePojo.setSongPath(j.getString("songPath"));
                onlinePojos.add(onlinePojo);
            }
        } catch (Exception e) { 
            e.printStackTrace(); 
            Log.e("AsyncTaskError", "解析JSON失败: " + e.getMessage());
        }
        return null;
    }
    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        // 通知适配器数据已更新
        onlinehome_adpater.notifyDataSetChanged();
    }
}

2. 初始化列表与适配器的正确顺序

在onCreateView里要先初始化onlinePojos,再创建适配器,确保适配器拿到的是有效的列表引用:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    v = inflater.inflate(R.layout.activity_onlinesong_home, container, false);
    song = v.findViewById(R.id.online_song);
    weeklytop = v.findViewById(R.id.online_trainding);
    week = v.findViewById(R.id.online_txtview);
    url = "https://burdened-committee.000webhostapp.com/musicbox/display.php";
    
    // 先初始化列表
    onlinePojos = new ArrayList<OnlinePojo>();
    // 再创建适配器,传入初始化后的列表
    onlinehome_adpater = new Onlinehome_Adpater(context, onlinePojos);
    
    weeklytop.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
    // 先设置空适配器,避免AsyncTask执行前RecyclerView无适配器
    weeklytop.setAdapter(onlinehome_adpater);
    
    new onlinesongdisplay().execute();
    return v;
}

3. 检查POJO字段与JSON键的匹配

确认后端返回的JSON键名和你解析时用的完全一致:

  • 比如你用j.getString("songname"),要确保JSON里的键是"songname"而不是"songName"或其他拼写
  • 同理"albumname"要和后端返回的键名完全匹配,手动赋值时只要解析键名正确,POJO字段名可以和JSON键名不同

4. 适配器的小优化

适配器里的列表变量名建议遵循Java命名规范(小写开头),避免和类名混淆:

// 修改适配器构造方法
private ArrayList<OnlinePojo> onlinePojos; // 小写开头
public Onlinehome_Adpater(Context c,ArrayList<OnlinePojo> onlinePojos) {
    context=c;
    this.onlinePojos=onlinePojos;
}

// 重写getItemCount时用修改后的变量名,增加空判断
@Override
public int getItemCount() { 
    return onlinePojos != null ? onlinePojos.size() : 0; 
}

额外调试建议

  • 在doInBackground里打印result,确认拿到的JSON数据是正确的
  • 在循环里打印每个解析后的onlinePojo字段,确认数据确实被正确赋值
  • 在onBindViewHolder里打印position和onlinePojo的内容,排查适配器是否拿到数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:29:18