Android使用Volley处理网络请求时JSON遍历及ListView显示异常问题
问题原因分析
- ListView显示异常:默认使用
ArrayAdapter绑定自定义实体类时,系统会自动调用对象的toString()方法渲染内容,你没有重写该方法,默认输出包名.类名@内存地址格式的内容,就是你看到的包名加数字的效果。 - JSON遍历不便:实体类中直接存储
JSONObject、JSONArray类型,每次取嵌套字段都需要处理JSON异常,使用成本高、易出错。 - 现有代码隐含bug:你定义的
WeatherReportModel只有带参构造方法,但实例化时调用了无参构造new WeatherReportModel(),缺少无参构造会直接编译报错;同时pop字段定义为double类型,解析时用getLong()取值会丢失精度。
解决方案
1. 重构实体类,拆分嵌套JSON结构
把所有嵌套的JSON节点都拆解为普通Java字段,避免直接操作JSON对象:
// 嵌套的Main实体类 public class Main { private double temp; private double feels_like; private double temp_min; private double temp_max; private int pressure; private int sea_level; private int grnd_level; private int humidity; private double temp_kf; // 补全get、set方法 } // 嵌套的Weather实体类 public class Weather { private int id; private String main; private String description; private String icon; // 补全get、set方法 } // 嵌套的Clouds实体类 public class Clouds { private int all; // 补全get、set方法 } // 嵌套的Wind实体类 public class Wind { private double speed; private int deg; private double gust; // 补全get、set方法 } // 嵌套的Sys实体类 public class Sys { private String pod; // 补全get、set方法 } // 主实体类 public class WeatherReportModel { private int dt; private Main main; private List<Weather> weather; private Clouds clouds; private Wind wind; private int visibility; private double pop; private Sys sys; private String dt_txt; // 补全无参构造、带参构造以及所有字段的get、set方法 // 重写toString方法,用于默认Adapter展示 @Override public String toString() { return "日期:" + dt_txt + "\n温度:" + main.getTemp() + "\n天气:" + weather.get(0).getDescription(); } }
2. 修复Volley回调解析逻辑
调整字段解析逻辑,修复pop字段取值错误:
public void getWeather(VolleyResponseListener forecast) { List<WeatherReportModel> weatherReportModels = new ArrayList<>(); JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { JSONArray weather_list = response.getJSONArray("list"); for (int i = 0; i < weather_list.length(); i++) { WeatherReportModel one_day_weather = new WeatherReportModel(); JSONObject first_day_from_api = weather_list.getJSONObject(i); one_day_weather.setDt(first_day_from_api.getInt("dt")); // 解析main节点 JSONObject mainJson = first_day_from_api.getJSONObject("main"); Main main = new Main(); main.setTemp(mainJson.getDouble("temp")); main.setFeels_like(mainJson.getDouble("feels_like")); main.setTemp_min(mainJson.getDouble("temp_min")); main.setTemp_max(mainJson.getDouble("temp_max")); main.setPressure(mainJson.getInt("pressure")); main.setSea_level(mainJson.getInt("sea_level")); main.setGrnd_level(mainJson.getInt("grnd_level")); main.setHumidity(mainJson.getInt("humidity")); main.setTemp_kf(mainJson.getDouble("temp_kf")); one_day_weather.setMain(main); // 解析weather数组 JSONArray weatherJsonArr = first_day_from_api.getJSONArray("weather"); List<Weather> weatherList = new ArrayList<>(); for (int j = 0; j < weatherJsonArr.length(); j++) { JSONObject weatherJson = weatherJsonArr.getJSONObject(j); Weather weather = new Weather(); weather.setId(weatherJson.getInt("id")); weather.setMain(weatherJson.getString("main")); weather.setDescription(weatherJson.getString("description")); weather.setIcon(weatherJson.getString("icon")); weatherList.add(weather); } one_day_weather.setWeather(weatherList); // 解析clouds节点 JSONObject cloudsJson = first_day_from_api.getJSONObject("clouds"); Clouds clouds = new Clouds(); clouds.setAll(cloudsJson.getInt("all")); one_day_weather.setClouds(clouds); // 解析wind节点 JSONObject windJson = first_day_from_api.getJSONObject("wind"); Wind wind = new Wind(); wind.setSpeed(windJson.getDouble("speed")); wind.setDeg(windJson.getInt("deg")); wind.setGust(windJson.getDouble("gust")); one_day_weather.setWind(wind); one_day_weather.setVisibility(first_day_from_api.getInt("visibility")); // 修复pop字段取值方式 one_day_weather.setPop(first_day_from_api.getDouble("pop")); // 解析sys节点 JSONObject sysJson = first_day_from_api.getJSONObject("sys"); Sys sys = new Sys(); sys.setPod(sysJson.getString("pod")); one_day_weather.setSys(sys); one_day_weather.setDt_txt(first_day_from_api.getString("dt_txt")); weatherReportModels.add(one_day_weather); } forecast.onResponse(weatherReportModels); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); } }); MySingleton.getInstance(context).addToRequestQueue(request); }
3. ListView渲染优化
如果你只需要展示简单内容,直接用默认ArrayAdapter即可,上面已经重写了toString()方法,会直接输出你定义的内容;如果需要展示更复杂的布局、多样式内容,建议自定义BaseAdapter或者改用RecyclerView实现。
内容的提问来源于stack exchange,提问作者Jaison.Chipuka
相关产品推荐
相关产品推荐

