JSON Array итерация в Android / Java

148

Я создаю приложение для Android, которое необходимо загрузить и синхронизировать с онлайн-базой данных. Я отправляю свой запрос из приложения на страницу php, которая возвращает соответствующие строки из базы данных в формате JSON.

Может кто-нибудь, пожалуйста, скажите мне лучший способ перебрать массив JSON?

Я получаю массив объектов:

[{json object},{json object},{json object}]

Какой самый простой фрагмент кода я мог бы использовать для доступа к JSONObjects в массиве?

РЕДАКТИРОВАТЬ: теперь, когда я думаю об этом, метод, который я использовал для итерации цикла был:

for (String row: json){
     id = row.getInt("id");
     name = row.getString("name");
     password = row.getString("password");
}

Так что я думаю, что смог каким-то образом превратить возвращаемый Json в итеративный массив. Есть идеи, как мне этого добиться?

Я извиняюсь за свою неопределенность, но у меня это сработало на примере, который я нашел в Интернете, и с тех пор не смог его найти.

Кевин Брэдшоу
источник
1
проверьте следующую ссылку: androidbeasts.wordpress.com/2015/08/04/json-parsing-tutorial
Aakash

Ответы:

67

Я сделал это двумя разными способами,

1.) сделать карту

        HashMap<String, String> applicationSettings = new HashMap<String,String>();
        for(int i=0; i<settings.length(); i++){
            String value = settings.getJSONObject(i).getString("value");
            String name = settings.getJSONObject(i).getString("name");
            applicationSettings.put(name, value);
        }

2.) сделать JSONArray из имен

    JSONArray names = json.names();
    JSONArray values = json.toJSONArray(names);
    for(int i=0; i<values.length(); i++){
        if (names.getString(i).equals("description")){
            setDescription(values.getString(i));
        }
        else if (names.getString(i).equals("expiryDate")){
            String dateString = values.getString(i);
            setExpiryDate(stringToDateHelper(dateString)); 
        }
        else if (names.getString(i).equals("id")){
            setId(values.getLong(i));
        }
        else if (names.getString(i).equals("offerCode")){
            setOfferCode(values.getString(i));
        }
        else if (names.getString(i).equals("startDate")){
            String dateString = values.getString(i);
            setStartDate(stringToDateHelper(dateString));
        }
        else if (names.getString(i).equals("title")){
            setTitle(values.getString(i));
        }
    }
Натан Шверманн
источник
335

Я думаю, что этот код короткий и понятный:

int id;
String name;
JSONArray array = new JSONArray(string_of_json_array);
for (int i = 0; i < array.length(); i++) {
    JSONObject row = array.getJSONObject(i);
    id = row.getInt("id");
    name = row.getString("name");
}

Это то, что вы искали?

Vipw
источник
3
Красиво и просто! Прекрасно работает!
Кервин Рамен
5
обратите внимание, что если вы отправляете «массив», который не имеет последовательных чисел, вы должны использовать JSONObject
max4ever
да, это прекрасно, но в то время как большое количество данных обрабатывается очень медленно :(
Ахмад Арслан
@ArslanAhmad Если у вас большой объем данных, вы не хотите создавать весь массив объектов json в памяти. Вместо этого используйте SAX-подобный подход. Смотрите здесь: stackoverflow.com/questions/10657725/…
vipw
это не работает для меня. я получаю исключение JSON из-за "{" скобки, окружающей объект?
filthy_wizard
7

К сожалению, JSONArray не поддерживает foreachзаявления, такие как:

for(JSONObject someObj : someJsonArray) {
    // do something about someObj
    ....
    ....
}

Мечта
источник
да, но он возвращает объект, а не JSONObject
Ошибка
3
Класс JSONArray не реализует интерфейс Iterable
Jorgesys
4

Когда я попробовал предложение @ vipw, я столкнулся с этим исключением: The method getJSONObject(int) is undefined for the type JSONArray

Это сработало для меня вместо:

int myJsonArraySize = myJsonArray.size();

for (int i = 0; i < myJsonArraySize; i++) {
    JSONObject myJsonObject = (JSONObject) myJsonArray.get(i);

    // Do whatever you have to do to myJsonObject...
}
Грэм С.
источник
Для Android я изменил myJsonArray.size () на myJsonArray.length () вместо этого
Rishiraj Purohit
3

Если вы используете реализацию JSON.org Java с открытым исходным кодом, вы можете просто заставить JSONArray реализовать Iterableинтерфейс и добавить следующий метод в класс:

@Override
public Iterator iterator() {
    return this.myArrayList.iterator();
}

Это сделает все экземпляры JSONArray итеративными, что означает, что for (Object foo : bar)синтаксис теперь будет работать с ним (обратите внимание, что foo должен быть объектом, потому что у JSONArrays нет объявленного типа). Все это работает, потому что класс JSONArray поддерживается простым ArrayList, который уже повторяется. Я полагаю, что другие реализации с открытым исходным кодом было бы так же легко изменить.

Thunderforge
источник
1
Что интересно, когда-то реализация JSON.org имела Итератор в классе JSONArray, но они удалили его: github.com/douglascrockford/JSON-java/commit/…
vipw
@vipw Я однажды написал им по электронной почте о реализации Iterable, но они сказали, что в конечном итоге не смогут, потому что это нарушит совместимость с Java 1.4. Возможно, именно поэтому он был удален в коммите.
Thunderforge
3

В массивах ищите:

JSONArray menuitemArray = popupObject.getJSONArray("menuitem"); 
Пол Берк
источник
2

Вы используете один и тот же объект Cast для каждой записи. На каждой итерации вы просто меняли один и тот же объект, вместо этого создавая новый.

Этот код должен это исправить:

JSONArray jCastArr = jObj.getJSONArray("abridged_cast");
ArrayList<Cast> castList= new ArrayList<Cast>();

for (int i=0; i < jCastArr.length(); i++) {
    Cast person = new Cast();  // create a new object here
    JSONObject jpersonObj = jCastArr.getJSONObject(i);

    person.castId = (String) jpersonObj.getString("id");
    person.castFullName = (String) jpersonObj.getString("name");

    castList.add(person);
}
details.castList = castList;
Andriya
источник
1

Итерируя по массиву JSON (org.json.JSONArray, встроенный в Android), следите за нулевыми объектами; например, вы можете получить "null"вместо нуля строки.

Чек может выглядеть так:

s[i] = array.isNull(i) ? null : array.getString(i);
18446744073709551615
источник