Android:在另一个JSON数组内部解析JSON数组

时间:2019-01-07 21:35:23

标签: android arrays json

我是JSON解析的新手,但我一直无法解决JSONArrays和JSONObjects以及如何进行导航的麻烦。我的应用程序解析JSON数据并将其显示在回收者视图中。 JSON响应包含三个我要从中获取数据的JSON数组。办公室,官员和地址数组。这里的问题是地址数组在Officials数组内部,我不知道如何解析该数据。该应用程序可以很好地处理某些数据,但是当我尝试解析地址数组中的数据时,我从logcat中收到错误消息。这是整个JSON响应

   {
 "normalizedInput": {
  "line1": "2613 Irvington Avenue",
  "city": "San Bernardino",
  "state": "CA",
  "zip": "92407"
 },
 "offices": [
  {
   "name": "President of the United States",
   "levels": [
    "country"
   ],
   "roles": [
    "headOfState",
    "headOfGovernment"
   ]
  },
  {
   "name": "Vice-President of the United States",
   "levels": [
    "country"
   ],
   "roles": [
    "deputyHeadOfGovernment"
   ]
  },
  {
   "name": "United States Senate",
   "levels": [
    "country"
   ],
   "roles": [
    "legislatorUpperBody"
   ]
  },
  {
   "name": "United States House of Representatives CA-31",
   "levels": [
    "country"
   ],
   "roles": [
    "legislatorLowerBody"
   ]
  },
  {
   "name": "Governor",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "headOfGovernment"
   ]
  },
  {
   "name": "Lieutenant Governor",
   "levels": [
    "administrativeArea1"
   ],
   "roles": [
    "deputyHeadOfGovernment"
   ]
  },
  {
   "name": "City Treasurer"
  },
  {
   "name": "Mayor"
  },
  {
   "name": "City Attorney"
  },
  {
   "name": "City Clerk"
  },
  {
   "name": "Sheriff-Coroner"
  },
  {
   "name": "Auditor-Controller-Treasurer-Tax Collector"
  },
  {
   "name": "District Attorney"
  },
  {
   "name": "Assessor-Clerk-Recorder"
  },
  {
   "name": "San Bernardino County Superior Court Judge"
  },
  {
   "name": "CA State Assembly District 40"
  },
  {
   "name": "CA State Senate District 23"
  },
  {
   "name": "Board of Supervisors, District 5"
  },
  {
   "name": "Secretary of State"
  },
  {
   "name": "State Treasurer"
  },
  {
   "name": "Attorney General"
  },
  {
   "name": "State Superintendent of Public Instruction"
  },
  {
   "name": "State Controller"
  },
  {
   "name": "Insurance Commissioner"
  }
 ],
 "officials": [
  {
   "name": "Donald J. Trump",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "potus"
    },
    {
     "type": "YouTube",
     "id": "whitehouse"
    }
   ]
  },
  {
   "name": "Mike Pence",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "VP"
    }
   ]
  },
  {
   "name": "Kamala D. Harris",
   "address": [
    {
     "line1": "112 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3553"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "KamalaHarris"
    },
    {
     "type": "YouTube",
     "id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
    }
   ]
  },
  {
   "name": "Dianne Feinstein",
   "address": [
    {
     "line1": "331 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3841"
   ],
   "photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
   "channels": [
    {
     "type": "Facebook",
     "id": "SenatorFeinstein"
    },
    {
     "type": "Twitter",
     "id": "SenFeinstein"
    },
    {
     "type": "YouTube",
     "id": "SenatorFeinstein"
    }
   ]
  },
  {
   "name": "Pete Aguilar",
   "address": [
    {
     "line1": "1223 Longworth House Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20515"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 225-3201"
   ],
   "photoUrl": "https://aguilar.house.gov/sites/aguilar.house.gov/files/styles/congress_image_medium/public/wysiwyg_uploaded/Headshot_0.jpg?itok=LSt7qkOV",
   "channels": [
    {
     "type": "Facebook",
     "id": "reppeteaguilar"
    },
    {
     "type": "Twitter",
     "id": "RepPeteAguilar"
    },
    {
     "type": "YouTube",
     "id": "UCIXCmfuRWrbgdTw257_lxJQ"
    },
    {
     "type": "YouTube",
     "id": "UCxwbFLOlKDsXrwizV5jah7g"
    }
   ]
  },
  {
   "name": "Edmund G. Brown Jr.",
   "address": [
    {
     "line1": "c/o State Capitol",
     "line2": "Suite 1173",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-2841"
   ],
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+JerryBrown"
    },
    {
     "type": "Facebook",
     "id": "jerrybrown"
    },
    {
     "type": "Twitter",
     "id": "JerryBrownGov"
    }
   ]
  },
  {
   "name": "Gavin Newsom",
   "address": [
    {
     "line1": "State Capitol",
     "line2": "Suite 1114",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-8994"
   ],
   "photoUrl": "http://www.ltg.ca.gov/images/newsimages/i2.png",
   "emails": [
    "gavin@gavinnewsom.com"
   ],
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+GavinNewsom"
    },
    {
     "type": "Facebook",
     "id": "GavinNewsom"
    },
    {
     "type": "Twitter",
     "id": "gavinnewsom"
    }
   ]
  },
  {
   "name": "David C. Kennedy",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "2nd Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5022"
   ]
  },
  {
   "name": "R. Carey Davis",
   "address": [
    {
     "line1": "300 N. \"D\" Street - 6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5133"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "MayorCareyDavis"
    }
   ]
  },
  {
   "name": "Gary D. Saenz",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5355"
   ],
   "emails": [
    "Attorney@sbcity.org"
   ]
  },
  {
   "name": "Georgeann \"Gigi\" Hanna",
   "address": [
    {
     "line1": "300 N. \"D\" Street",
     "line2": "2nd Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92418"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 384-5002"
   ]
  },
  {
   "name": "John McMahon",
   "address": [
    {
     "line1": "655 East Third Street",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(760) 956-5001"
   ],
   "emails": [
    "paffairs@sbcsd.org"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "sbcountysheriff"
    },
    {
     "type": "Twitter",
     "id": "sbcountysheriff"
    }
   ]
  },
  {
   "name": "Oscar Valdez",
   "address": [
    {
     "line1": "222 W. Hospitality Lane",
     "line2": "4th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 382-7014"
   ]
  },
  {
   "name": "Michael Ramos",
   "address": [
    {
     "line1": "303 West 3rd Street",
     "line2": "6th Floor",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 382-3669"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "SanBernardinoCountyDistrictAttorney"
    },
    {
     "type": "Twitter",
     "id": "sbcountyda"
    }
   ]
  },
  {
   "name": "Bob Dutton",
   "address": [
    {
     "line1": "First Floor",
     "line2": "222 W. Hospitality Lane",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(855) 732-2575"
   ]
  },
  {
   "name": "Denise Trager Dvorak",
   "party": "Nonpartisan"
  },
  {
   "name": "James C. Ramos",
   "address": [
    {
     "line1": "PO BOX 942849",
     "city": "Sacramento",
     "state": "CA",
     "zip": "94249"
    }
   ],
   "party": "Democratic Party",
   "phones": [
    "(916) 319-2040"
   ]
  },
  {
   "name": "Mike Morrell",
   "address": [
    {
     "line1": "STATE CAPITOL",
     "line2": "1303 10TH ST RM 3056",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Republican",
   "phones": [
    "(909) 919-7731"
   ],
   "photoUrl": "http://senate.ca.gov/sites/senate.ca.gov/files/senator_photos/morrell-mike.jpg",
   "emails": [
    "senator.morrell@senate.ca.gov"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "MikeMorrellGOP"
    },
    {
     "type": "Facebook",
     "id": "MikeMorrellGOP"
    }
   ]
  },
  {
   "name": "Josie Gonzales",
   "address": [
    {
     "line1": "385 N. Arrowhead Ave.",
     "line2": "5th Fl.",
     "city": "San Bernardino",
     "state": "CA",
     "zip": "92415"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(909) 387-4565"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "supervisorgonzales"
    },
    {
     "type": "Twitter",
     "id": "SupervisorJosie"
    }
   ]
  },
  {
   "name": "Alex Padilla",
   "address": [
    {
     "line1": "1500 11th Street,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 653-7244"
   ],
   "emails": [
    "secretary.padilla@sos.ca.gov"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "CaliforniaSOS"
    },
    {
     "type": "Twitter",
     "id": "CASOSvote"
    }
   ]
  },
  {
   "name": "John Chiang",
   "address": [
    {
     "line1": "P.O. Box 942809",
     "city": "Sacramento",
     "state": "CA",
     "zip": "94209"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 653-2995"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "STONewsroom"
    }
   ]
  },
  {
   "name": "Xavier Becerra",
   "address": [
    {
     "line1": "Office of the Attorney General",
     "line2": "1300 \"I\" Street",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-9555"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "XavierBecerra"
    },
    {
     "type": "Twitter",
     "id": "AGBecerra"
    }
   ]
  },
  {
   "name": "Tom Torlakson",
   "address": [
    {
     "line1": "1430 N Street,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Nonpartisan",
   "phones": [
    "(916) 319-0800"
   ],
   "emails": [
    "superintendent@cde.ca.gov"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "CAEducation"
    },
    {
     "type": "Twitter",
     "id": "cadepted"
    }
   ]
  },
  {
   "name": "Betty T. Yee",
   "address": [
    {
     "line1": "P.O. Box 942850",
     "city": "Sacramento",
     "state": "CA",
     "zip": "94250"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 445-2636"
   ],
   "channels": [
    {
     "type": "Facebook",
     "id": "137732083043662"
    },
    {
     "type": "Twitter",
     "id": "CAController"
    }
   ]
  },
  {
   "name": "Dave Jones",
   "address": [
    {
     "line1": "300 Capitol Mall,",
     "city": "Sacramento",
     "state": "CA",
     "zip": "95814"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(916) 492-3500"
   ],
   "channels": [
    {
     "type": "GooglePlus",
     "id": "108233445289196913395"
    },
    {
     "type": "Facebook",
     "id": "insurancecagov"
    },
    {
     "type": "Twitter",
     "id": "CDINews"
    }
   ]
  }
 ]
}

解析函数:

  //fetch json data from Civic API
    private void getData(){
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setMessage("Loading...");
        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                progressDialog.dismiss();
                try{
                    JSONObject jsonObject = new JSONObject(response);
                    //first loop through offices array. Retrieve officeName value
                    JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                    JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                    for (int i = 0; i < officesArray.length(); i++) {
                        JSONObject jsonOffices = officesArray.getJSONObject(i);
                        JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                        JSONObject jsonAddress = jsonOfficials.getJSONObject("address");
                        String line1 = jsonAddress.getJSONObject("address").getString("line1");
                        String city = jsonAddress.getJSONObject("address").getString("city");
                        String state = jsonAddress.getJSONObject("address").getString("state");
                        String zip = jsonAddress.getJSONObject("address").getString("zip");
                        if (jsonOfficials.has("photoUrl")) {
                            Reps reps1 = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"),
                                    jsonOfficials.getString("photoUrl"),
                                    line1,
                                    city,
                                    state,
                                    zip
                            );

                            repList.add(reps1);
                        } else {
                            Reps reps2 = new Reps(jsonOffices.getString("name"),
                                    jsonOfficials.getString("name"),
                                    jsonOfficials.getString("party"),
                                    line1,
                                    city,
                                    state,
                                    zip
                           );

                            repList.add(reps2);
                        }
                    }
                    adapter = new RepRvAdapter(repList, getApplicationContext());
                    myrv.setAdapter(adapter);
                }catch (JSONException e){
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("Volley", error.toString());
                progressDialog.dismiss();
            }
        });
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }

logcat错误表明无法将JSONArray转换为JSONObject enter image description here

我了解为什么会收到此错误。这是因为我正在JSON数组上调用.getJSONObject,但是我不确定如何修复它。

编辑:添加了一些日志标签以进行故障排除。似乎没有发现Denise Trager Dvorak的地址值。这是错误所在。我如何解决它? enter image description here

1 个答案:

答案 0 :(得分:1)

正如您所说的address是一个JSONArray,其中包含带有地址信息的对象。

因此,您需要访问数组中的第一个对象,并从那里获取信息,如下所示:

    //fetch json data from Civic API
private void getData(){
    final ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading...");
    progressDialog.show();

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            progressDialog.dismiss();
            try{
                JSONObject jsonObject = new JSONObject(response);
                //first loop through offices array. Retrieve officeName value
                JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                for (int i = 0; i < officesArray.length(); i++) {
                    JSONObject jsonOffices = officesArray.getJSONObject(i);
                    JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                    JSONArray jsonAddress = jsonOfficials.getJSONArray("address");
                    String line1 = jsonAddress.getJSONObject(0).getString("line1");
                    String city = jsonAddress.getJSONObject(0).getString("city");
                    String state = jsonAddress.getJSONObject(0).getString("state");
                    String zip = jsonAddress.getJSONObject(0).getString("zip");
                    if (jsonOfficials.has("photoUrl")) {
                        Reps reps1 = new Reps(jsonOffices.getString("name"),
                                jsonOfficials.getString("name"),
                                jsonOfficials.getString("party"),
                                jsonOfficials.getString("photoUrl"),
                                line1,
                                city,
                                state,
                                zip
                        );

                        repList.add(reps1);
                    } else {
                        Reps reps2 = new Reps(jsonOffices.getString("name"),
                                jsonOfficials.getString("name"),
                                jsonOfficials.getString("party"),
                                line1,
                                city,
                                state,
                                zip
                        );

                        repList.add(reps2);
                    }
                }
                adapter = new RepRvAdapter(repList, getApplicationContext());
                myrv.setAdapter(adapter);
            }catch (JSONException e){
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Volley", error.toString());
            progressDialog.dismiss();
        }
    });
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

EDIT1:

我修改了代码,以使用提供的json在我的机器上本地尝试,并且一切正常。在这里您可以看到图像:

Adapted code

Results

能否请您将一些结果记录在我先前发布的解决方案中,并检查某些对象是否没有地址,或者我们是否缺少其他内容。