Android中读取JSON Array时出现错误的技术咨询
解决Android中JSON Array解析错误的方案
嘿,我帮你梳理下这个JSON解析的问题!先看你提供的JSON结构,里面的options字段是个“变色龙”——有的是数组,有的是对象,这大概率是你解析时出错的核心原因。下面一步步给你讲怎么在Android里正确处理它:
先明确JSON的核心结构
你的JSON最外层是一个对象,包含名为data的数组,数组里的每个元素又嵌套了一个data对象,重点是这个嵌套data里的options:
- 第一个元素的
options是JSON数组(包含多个display项) - 第二个元素的
options是JSON对象(包含left和right两个子对象)
如果解析时没区分这两种类型,直接强制转成数组或对象,肯定会抛类型转换异常!
方案1:用原生JSONObject/JSONArray解析(无第三方库)
这种方式适合不想引入第三方库的场景,关键是先判断options的类型再处理:
// 假设你的JSON字符串存在jsonStr变量中 try { JSONObject rootObj = new JSONObject(jsonStr); JSONArray dataArray = rootObj.getJSONArray("data"); // 遍历外层data数组 for (int i = 0; i < dataArray.length(); i++) { JSONObject itemObj = dataArray.getJSONObject(i); // 提取外层字段 String id = itemObj.getString("id"); int type = itemObj.getInt("type"); int order = itemObj.getInt("order"); // 提取嵌套的data对象 JSONObject innerData = itemObj.getJSONObject("data"); int innerType = innerData.getInt("type"); int innerOrder = innerData.getInt("order"); // 用optBoolean处理可选字段,避免字段不存在时崩溃 boolean required = innerData.optBoolean("required", false); // 重点:判断options的类型 Object optionsObj = innerData.get("options"); if (optionsObj instanceof JSONArray) { // 处理数组类型的options(比如第一个元素的星级选项) JSONArray optionsArray = (JSONArray) optionsObj; for (int j = 0; j < optionsArray.length(); j++) { JSONObject optionItem = optionsArray.getJSONObject(j); String displayText = optionItem.getString("display"); // 这里可以把displayText存入列表或做其他处理 } } else if (optionsObj instanceof JSONObject) { // 处理对象类型的options(比如第二个元素的左右选项) JSONObject optionsObject = (JSONObject) optionsObj; JSONObject leftOpt = optionsObject.getJSONObject("left"); String leftGoto = leftOpt.getString("goto"); int leftDisplay = leftOpt.getInt("display"); JSONObject rightOpt = optionsObject.getJSONObject("right"); String rightGoto = rightOpt.getString("goto"); // 注意你给的JSON里right的display字段截断了,根据实际数据处理即可 } } } catch (JSONException e) { e.printStackTrace(); // 这里可以添加错误处理逻辑,比如提示解析失败 }
方案2:用Gson解析(更简洁,推荐)
如果项目里已经用了Gson,那定义实体类时要注意处理多类型的options和Java关键字goto:
第一步:定义实体类
import com.google.gson.annotations.SerializedName; import java.util.List; public class SurveyResponse { private List<SurveyItem> data; // Getter & Setter public List<SurveyItem> getData() { return data; } public void setData(List<SurveyItem> data) { this.data = data; } public static class SurveyItem { private String id; private int type; private int order; private SurveyInnerData data; // Getter & Setter public String getId() { return id; } public void setId(String id) { this.id = id; } public int getType() { return type; } public void setType(int type) { this.type = type; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public SurveyInnerData getData() { return data; } public void setData(SurveyInnerData data) { this.data = data; } public static class SurveyInnerData { // 注意:goto是Java关键字,必须用@SerializedName映射字段名 @SerializedName("goto") private String gotoTarget; private int type; private int order; // 用Object接收多类型的options,后续再判断类型 private Object options; private boolean required; private List<Object> answer; // Getter & Setter public String getGotoTarget() { return gotoTarget; } public void setGotoTarget(String gotoTarget) { this.gotoTarget = gotoTarget; } public int getType() { return type; } public void setType(int type) { this.type = type; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public Object getOptions() { return options; } public void setOptions(Object options) { this.options = options; } public boolean isRequired() { return required; } public void setRequired(boolean required) { this.required = required; } public List<Object> getAnswer() { return answer; } public void setAnswer(List<Object> answer) { this.answer = answer; } } } }
第二步:解析JSON字符串
import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; // 解析代码 Gson gson = new Gson(); SurveyResponse response = gson.fromJson(jsonStr, SurveyResponse.class); // 遍历处理每个SurveyItem for (SurveyResponse.SurveyItem item : response.getData()) { Object options = item.getData().getOptions(); if (options instanceof JsonArray) { // 处理数组类型的options JsonArray optionsArray = (JsonArray) options; // 遍历数组提取display内容... } else if (options instanceof JsonObject) { // 处理对象类型的options JsonObject optionsObj = (JsonObject) options; JsonObject leftOpt = optionsObj.getAsJsonObject("left"); // 提取left的字段... } }
常见错误避坑指南
- 类型转换异常:一定要先判断
options是数组还是对象,不要直接调用getJSONArray或getJSONObject - 关键字冲突:
goto是Java关键字,不能直接用作字段名,必须用@SerializedName映射 - 可选字段崩溃:对于可能不存在的字段(比如
required),用optXXX方法(原生)或者让实体类字段为Boolean(Gson),避免字段缺失时抛异常
内容的提问来源于stack exchange,提问作者Hugg
相关产品推荐
相关产品推荐

