Android中用Volley+Gson将JSON数组批量映射到Match POJO类
解决Volley+Gson转换JSON数组为POJO集合的问题
我来帮你排查下代码里的问题,然后给出可行的解决方案:
你的代码里存在几个关键问题:
- 集合未初始化:你声明了
ArrayList<Match> matches;但没有实例化,直接调用matches.addAll()会触发NullPointerException。 - Gson解析方式错误:你尝试直接把
JSONArray传给gson.fromJson(),但Gson默认不能直接解析JSONArray对象,需要先转成字符串;另外手动处理JSONObject和JSONArray其实没必要,用Gson直接解析整个响应会更简洁。 - 未通知适配器更新:数据更新后没有调用适配器的
notifyDataSetChanged(),RecyclerView不会刷新显示新数据。 - 无效动画代码:
recyclerView.setAnimation(n);里的n未定义,会导致编译错误。
解决方案一:创建根POJO类(推荐)
这种方式让Gson直接解析整个JSON响应,不用手动处理JSON结构,更易维护:
1. 创建对应整个响应的POJO类
public class CricketResponse { private List<Match> matches; private String v; private int ttl; private Provider provider; private int creditsLeft; // Getter for matches(其他字段的getter/setter按需添加) public List<Match> getMatches() { return matches; } } public class Provider { private String source; private String url; private String pubDate; // Getters and Setters } public class Match { private int unique_id; private String date; private String dateTimeGMT; private boolean squad; private String toss_winner_team; private String winner_team; private boolean matchStarted; private String type; // 处理JSON中带减号的字段,用@SerializedName映射 @SerializedName("team-1") private String team1; @SerializedName("team-2") private String team2; // Getters and Setters public String getTeam1() { return team1; } public String getTeam2() { return team2; } // 其他字段的getter/setter自行补充 }
2. 修改Activity中的代码
public class Main2Activity extends AppCompatActivity { RecyclerView recyclerView; ArrayList<Match> matches; MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recylcer_1); recyclerView = findViewById(R.id.recyler); // 初始化集合,避免空指针 matches = new ArrayList<>(); myAdapter = new MyAdapter(matches); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext()); recyclerView.setLayoutManager(layoutManager); // 移除无效的动画代码,或者正确初始化动画后再设置 // recyclerView.setAnimation(n); recyclerView.setAdapter(myAdapter); callCricket(); } public void callCricket() { CallApi callApi = new CallApi(); callApi.setVolleyInterface(new VolleyInterface() { @Override public void onSucess(String string) { Log.d("ApiCall_success", string); Gson gson = new Gson(); // 直接解析整个响应到CricketResponse对象 CricketResponse response = gson.fromJson(string, CricketResponse.class); // 更新数据并通知适配器 matches.clear(); matches.addAll(response.getMatches()); myAdapter.notifyDataSetChanged(); } @Override public void onError(String string) { Log.e("ApiCall_error", "请求失败:" + string); } }); } }
解决方案二:直接解析JSONArray字符串(无需根POJO)
如果你不想创建根POJO类,可以把JSONArray转为字符串后再用Gson解析:
修改onSucess方法内的代码:
@Override public void onSucess(String string) { Log.d("ApiCall_success", string); Gson gson = new Gson(); try { JSONObject jsonObject = new JSONObject(string); JSONArray jsonArray = jsonObject.getJSONArray("matches"); // 将JSONArray转为字符串,再解析为集合 Type matchListType = new TypeToken<ArrayList<Match>>(){}.getType(); ArrayList<Match> newMatches = gson.fromJson(jsonArray.toString(), matchListType); // 更新数据并通知适配器 matches.clear(); matches.addAll(newMatches); myAdapter.notifyDataSetChanged(); } catch (JSONException e) { e.printStackTrace(); Log.e("Parse_error", "JSON解析失败:" + e.getMessage()); } }
注意:这种方式同样需要确保Match类的字段用@SerializedName正确映射JSON中的特殊字段,并且提前初始化matches集合。
内容的提问来源于stack exchange,提问作者scott
相关产品推荐
相关产品推荐

