Android/Java新手:JSONArray含10个对象但仅显示前两项
Hey there! I can spot the issue right away—your parsing code is crashing mid-loop when it hits a book entry missing one of the required fields, which stops the rest of the items from being processed. Let's fix this step by step.
The Root Cause
When you use getString() or getJSONObject() on a JSONObject, if the specified key doesn't exist, it throws a JSONException. Your catch block logs the error but doesn't let the loop continue, so only the first two books (which have all the required fields) get added to your list.
The Fix: Use "Opt" Methods for Safe Parsing
Instead of strict getter methods, switch to their "opt" counterparts. These methods return a default value (or null) when the key is missing, instead of throwing an exception. Here's how to update your extractItemFromJson method:
private static List<BookItem> extractItemFromJson(String bookJSON) { // If the JSON string is empty or null, then return early. if (TextUtils.isEmpty(bookJSON)){ return null; } // Create an empty ArrayList that we can start adding books to List<BookItem> bookItems = new ArrayList<>(); // Try to parse the JSON response string. If there is a problem with the way the JSON is formatted, // a JSONException exception object will be thrown. // Catch the exception so the app doesnt crash, and print the error message to the logs. try { JSONObject baseJsonresponse = new JSONObject(bookJSON); JSONArray bookItemArray = baseJsonresponse.getJSONArray("items"); Log.e("QueryUtils", "length of array: " + bookItemArray.length()); for (int i = 0; i < bookItemArray.length(); i++) { JSONObject currentBook = bookItemArray.getJSONObject(i); JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo"); // Use optString with a default value for fields that might be missing String title = volumeInfo.optString("title", "No Title"); String subtitle = volumeInfo.optString("subtitle", ""); String previewLink = volumeInfo.optString("previewLink", ""); // Safely handle imageLinks (might not exist for some books) JSONObject imageLinks = volumeInfo.optJSONObject("imageLinks"); String thumbnail = ""; if (imageLinks != null) { thumbnail = imageLinks.optString("smallThumbnail", ""); } BookItem book = new BookItem(title, subtitle, thumbnail, previewLink); bookItems.add(book); } } catch (JSONException e) { Log.e("QueryUtils", "Problem parsing book at index: " + i, e); // Log which index failed } return bookItems; }
Key Changes Explained
optString("key", "defaultValue"): If the key doesn't exist, it returns your specified default value instead of throwing an error.optJSONObject("key"): Returnsnullif the key is missing, so we can check fornullbefore trying to access its fields (likesmallThumbnail).- Updated the catch block to log which index caused the error—this will help you debug specific entries if needed.
After making these changes, your loop will process all 10 book entries, even if some are missing optional fields like subtitle or imageLinks.
内容的提问来源于stack exchange,提问作者Phoenix. N

