【问题标题】:JSONException: Not a primitive array in parsing JSONArrayJSONException:解析 JSONArray 时不是原始数组
【发布时间】:2016-05-08 11:43:19
【问题描述】:

我正在处理的 JSON:

[
  {
    "score":2.860397,
    "show": {
      "id": 82,
      "url": "http://www.tvmaze.com/shows/82/game-of-thrones",
      "name": "Game of Thrones",
      "type": "Scripted",
      "language": "English",
      "genres": [
        "Drama", "Adventure", "Fantasy"
      ],
      "status": "Running",
      "runtime": 60,
      "premiered": "2011-04-17",
      "schedule": {
        "time": "21:00",
        "days": [ "Sunday" ]
      },
      "rating": {
        "average": 9.4
      },
      "weight": 100,
      "network": {
        "id": 8,
        "name": "HBO",
        "country": {
          "name": "United States",
          "code": "US",  
          "timezone": "America/New_York"
        }
      },
      "webChannel": null,
      "externals": {
        "tvrage": 24493,
        "thetvdb": 121361,
        "imdb": "tt0944947"
      },
      "image": { 
        "medium": "http://tvmazecdn.com/uploads/images/medium_portrait/53/132622.jpg",
        "original": "http://tvmazecdn.com/uploads/images/original_untouched/53/132622.jpg"
      },           
      "summary": "<p>Based on the bestselling book series A Song of Ice and Fire by George R.R. Martin, this sprawling new HBO drama is set in a world where summers span decades and winters can last a lifetime. From the scheming south and the savage eastern lands, to the frozen north and ancient Wall that protects the realm from the mysterious darkness beyond, the powerful families of the Seven Kingdoms are locked in a battle for the Iron Throne. This is a story of duplicity and treachery, nobility and honor, conquest and triumph. In the <strong><em>\"Game of Thrones\"</em></strong>, you either win or you die.</p>",
      "updated": 1462561599,
      "_links": {
        "self": {
          "href": "http://api.tvmaze.com/shows/82"
        }, 
        "previousepisode": {  
          "href": "http://api.tvmaze.com/episodes/664672"
         },
        "nextepisode": {
          "href": "http://api.tvmaze.com/episodes/664673"
        }
      }
    } 
  }
]

我的代码:

JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, final_url, (String)null,
    new Response.Listener<JSONArray>() {
        @Override
        public void onResponse(JSONArray response) {
            try {
                JSONArray jArray = new JSONArray(response);

                for(int i=0; i<jArray.length(); i++) {
                    JSONObject json_object = (JSONObject)jArray.get(i);
                    String name = json_object.getString("name");
                    System.out.println(name);
                }
            } catch(JSONException e) {
                System.out.println(e);
            }
        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            System.out.println(error);
        }
    }
);

我已经看到有很多这样的问题,但其中大多数涉及JSONObject 而不是JSONArray,我没有找到适合我的解决方案。

我仍然收到标题中提到的错误。有什么帮助吗?

更新: 到目前为止,除了 gson 之外的所有方法都尝试了,但仍然无法正常工作。 堆栈跟踪是:

05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     org.json.JSONException: Not a primitive array: class org.json.JSONArray
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at org.json.JSONArray.<init>(JSONArray.java:116)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.example.user.test.SearchActivity$2$override.onResponse(SearchActivity.java:134)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.example.user.test.SearchActivity$2$override.access$dispatch(SearchActivity.java)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.example.user.test.SearchActivity$2.onResponse(SearchActivity.java:0)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.example.user.test.SearchActivity$2.onResponse(SearchActivity.java:115)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:72)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at android.os.Looper.loop(Looper.java:135)
05-08 14:18:14.790 2628-2628/com.example.user.test W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5254)
05-08 14:18:14.797 2628-2628/com.example.user.test W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
05-08 14:18:14.797 2628-2628/com.example.user.test W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
05-08 14:18:14.801 2628-2628/com.example.user.test W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
05-08 14:18:14.801 2628-2628/com.example.user.test W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

更新 2: 我的 wole searchActivity.java 也许错误在其他地方(我删除了数组以查看它是否改变了任何东西,但没有):

公共类 SearchActivity 扩展 AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);



    final EditText editText = (EditText) findViewById(R.id.searchView);
    editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            boolean handled = false;
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                String query = editText.getText().toString();
                //doMySearch(query);
                clearQuery(query);
                handled = true;
            }
            return handled;
        }
    });


}

public void clearQuery(String query) {
    query = query.replaceAll("[^\\w\\s]","").replaceAll("\\s+","-"); //TVMaze API uses "-" as spaces

    doMySearch(query);

}


public void doMySearch(String query) {
    System.out.println("print if doMySearch was opened");
    System.out.println(query);
    List<Show> subscribedShowsList = new ArrayList<Show>();

    String url = "http://api.tvmaze.com/search/shows?q=";
    String final_url = url + query;

    RequestQueue mRequestQueue;

// Instantiate the cache
    Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap

// Set up the network to use HttpURLConnection as the HTTP client.
    Network network = new BasicNetwork(new HurlStack());

// Instantiate the RequestQueue with the cache and network.
    mRequestQueue = new RequestQueue(cache, network);



    JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, final_url, (String)null,
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {

                    System.out.println("print if we got to onResponse");
                    try {
                        JSONArray jArray = new JSONArray(response);

                        JSONObject joParent = response.getJSONObject(0);
                        JSONObject joShow = joParent.getJSONObject("show");
                        String name = joShow.getString("name");
                        System.out.println(name);

                    } catch(JSONException e) {
                        e.printStackTrace();

                    }

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    System.out.println(error);
                }
            });
    mRequestQueue.add(request);
    mRequestQueue.start();
}

}

【问题讨论】:

  • 如果你想使用Gson,我可以建议你并给你答案
  • 已经使用 GSON 发布了答案。看一眼。 ;-)

标签: android json


【解决方案1】:

希望这会有所帮助。

try {    

  JSONObject joParent = response.getJSONObject(0);

  JSONObject joShow = joParent.getJSONObject("show");

  String name = joShow.getString("name");

} catch (JSONException e) {
   e.printStackTrace();
} 

【讨论】:

  • 非常感谢它仍然无法正常工作。如果您愿意,请使用 stacktrace 更新我的帖子。
  • 请不要使用 JSONArray jArray = new JSONArray(response);因为响应已经是 JSONArray
  • 已解决。非常感谢你。现在我可以要求解释吗?为什么当我使用您的代码(此处不涉及 jArray)并且我只定义了 jArray 时它会引发错误?它不应该被忽略吗,因为它除了 declamation 之外没有在任何地方使用过?
  • Volley 直接将父 JSONArray 作为 onResponse() 的参数提供。如果您有字符串格式的最终​​响应,那么您应该创建父 JSONArray。
【解决方案2】:

  for(int i=0; i<jArray.length(); i++) {
            JSONObject json_object = null;
            JSONObject internalObject=null;
            try {
                json_object = (JSONObject)jArray.get(i);
                internalObject= (JSONObject) json_object.get("show");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            String name = null;
            try {
                name = internalObject.getString("name");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            System.out.println(name);


        }

节目是一个嵌套的 JSONObject 。用它替换你的 for 循环。

【讨论】:

  • 非常感谢它仍然无法正常工作。如果您愿意,请使用 stacktrace 更新我的帖子。
  • 以上已解决。还是谢谢你。
【解决方案3】:

我已使用 GSON 处理您的 JSON 响应。

假设,我们有以下模型类:

回复:

public class Response {
    @SerializedName("score")
    @Expose
    public double score;
    @SerializedName("show")
    @Expose
    public Show show;
}

显示:

public class Show {
    @SerializedName("id")
    @Expose
    public int id;
    @SerializedName("url")
    @Expose
    public String url;
    @SerializedName("name")
    @Expose
    public String name;
    @SerializedName("type")
    @Expose
    public String type;
    @SerializedName("language")
    @Expose
    public String language;
    @SerializedName("genres")
    @Expose
    public List<String> genres = new ArrayList<String>();
    @SerializedName("status")
    @Expose
    public String status;
    @SerializedName("runtime")
    @Expose
    public int runtime;
    @SerializedName("premiered")
    @Expose
    public String premiered;
    @SerializedName("schedule")
    @Expose
    public Schedule schedule;
    @SerializedName("rating")
    @Expose
    public Rating rating;
    @SerializedName("weight")
    @Expose
    public int weight;
    @SerializedName("network")
    @Expose
    public Network network;
    @SerializedName("webChannel")
    @Expose
    public Object webChannel;
    @SerializedName("externals")
    @Expose
    public Externals externals;
    @SerializedName("image")
    @Expose
    public Image image;
    @SerializedName("summary")
    @Expose
    public String summary;
    @SerializedName("updated")
    @Expose
    public int updated;
    @SerializedName("_links")
    @Expose
    public Links Links;
}

时间表:

public class Schedule {
    @SerializedName("time")
    @Expose
    public String time;
    @SerializedName("days")
    @Expose
    public List<String> days = new ArrayList<String>();
}

评分:

public class Rating {
    @SerializedName("average")
    @Expose
    public double average;
}

网络:

public class Network {
    @SerializedName("id")
    @Expose
    public int id;
    @SerializedName("name")
    @Expose
    public String name;
    @SerializedName("country")
    @Expose
    public Country country;
}

国家:

public class Country {
    @SerializedName("name")
    @Expose
    public String name;
    @SerializedName("code")
    @Expose
    public String code;
    @SerializedName("timezone")
    @Expose
    public String timezone;
}

外部:

public class Externals {
    @SerializedName("tvrage")
    @Expose
    public int tvrage;
    @SerializedName("thetvdb")
    @Expose
    public int thetvdb;
    @SerializedName("imdb")
    @Expose
    public String imdb;
}

图片:

public class Image {
    @SerializedName("medium")
    @Expose
    public String medium;
    @SerializedName("original")
    @Expose
    public String original;
}

链接:

public class Links {
    @SerializedName("self")
    @Expose
    public Self self;
    @SerializedName("previousepisode")
    @Expose
    public Previousepisode previousepisode;
    @SerializedName("nextepisode")
    @Expose
    public Nextepisode nextepisode;
}

自我:

public class Self {
    @SerializedName("href")
    @Expose
    public String href;
}

下一集:

public class Nextepisode {
    @SerializedName("href")
    @Expose
    public String href;
}

上一集:

public class Previousepisode {
    @SerializedName("href")
    @Expose
    public String href;
}

解析真的很简单:

String json = ""; // Your response; for simplicity I stringified it.
Gson gson = new GsonBuilder().create();
Type showType = new TypeToken<Collection<Response>>(){}.getType();
ArrayList<Response> responses = gson.fromJson(json, showType);

for(Response response : responses) {
    Log.d("Response - json", response.toString());
}

最难的部分是,你的响应实际上是一个数组而不是对象,所以你必须parse it as described in the example

使用上述代码的结果:

【讨论】:

  • 非常感谢。非常感谢以如此干净和简单的方式呈现所有这些的努力!希望我能尽快使用它。
【解决方案4】:

当您处理 json 并处理解析错误时,这是​​解决问题的最简单方法。

  1. 查找 json 验证器并检查 json 是否有效。您可以在谷歌上输入json validate 并使用网站。
  2. 在查看 json 时,name 嵌套在 show 中。因此,您实际上想要

    String name = json_object.getJSONObject("show").getString("name");
    

希望这可以解决您考虑到 jsons 的未来问题

【讨论】:

    猜你喜欢
    • 2014-06-02
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多