Iteracja tablicy JSON w systemie Android / Java

148

Buduję aplikację na Androida, która musi pobrać i zsynchronizować się z bazą danych online. Wysyłam zapytanie z aplikacji do strony php, która zwraca odpowiednie wiersze z bazy danych w formacie JSON.

czy ktoś może mi powiedzieć, jak najlepiej wykonać iterację przez tablicę JSON?

Otrzymuję tablicę obiektów:

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

Jaki jest najprostszy fragment kodu, którego mogę użyć, aby uzyskać dostęp do obiektów JSONObject w tablicy?

EDYCJA: teraz, gdy o tym myślę, metoda, której użyłem do iteracji pętli, była:

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

Więc wydaje mi się, że udało mi się w jakiś sposób zamienić zwrócone Json na tablicę iterowalną. Jakieś pomysły, jak mogę to osiągnąć?

Przepraszam za moją włóczęgę, ale działało to z przykładu, który znalazłem w Internecie i od tego czasu nie mogę go znaleźć.

Kevin Bradshaw
źródło
1
sprawdź następujący link: androidbeasts.wordpress.com/2015/08/04/json-parsing-tutorial
Aakash

Odpowiedzi:

67

Zrobiłem to na dwa różne sposoby,

1.) Zrób mapę

        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.) zrób tablicę nazw w JSONA

    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));
        }
    }
Nathan Schwermann
źródło
335

Myślę, że ten kod jest krótki i jasny:

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");
}

Czy tego szukałeś?

vipw
źródło
3
Ładnie i prosto! Działa świetnie!
Kervin Ramen,
5
zwróć uwagę, że jeśli wyślesz „tablicę”, która nie ma kolejnych numerów, musisz użyć JSONObject
max4ever
tak, jest idealny, ale podczas przetwarzania dużej ilości danych przetwarzanie jest bardzo powolne :(
Ahmad Arslan,
@ArslanAhmad Jeśli masz dużą ilość danych, nie chcesz tworzyć całej tablicy obiektów json w pamięci. Zamiast tego użyj podejścia podobnego do SAX. Zobacz tutaj: stackoverflow.com/questions/10657725/…
vipw
to nie działa dla mnie. otrzymuję wyjątek JSON z powodu nawiasu „{” otaczającego obiekt?
filthy_wizard
7

Niestety JSONArray nie obsługuje foreachstwierdzeń, takich jak:

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

Śnić
źródło
tak, ale zwraca obiekt nie JSONObject
błąd,
3
Klasa JSONArray nie implementuje
Iterowalnego
4

Kiedy wypróbowałem sugestię @ vipw, stanąłem przed tym wyjątkiem: The method getJSONObject(int) is undefined for the type JSONArray

Zamiast tego zadziałało dla mnie:

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...
}
Graham S.
źródło
W przypadku Androida zmieniłem zamiast tego myJsonArray.size () na myJsonArray.length ()
Rishiraj Purohit
3

Jeśli używasz implementacji JSON.org Java , która jest open source, możesz po prostu sprawić, by JSONArray zaimplementował Iterableinterfejs i dodać następującą metodę do klasy:

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

Spowoduje to, że wszystkie instancje JSONArray będą iterowalne, co oznacza, że for (Object foo : bar)składnia będzie teraz z nim działać (zauważ, że foo musi być obiektem, ponieważ JSONArray nie ma zadeklarowanego typu). Wszystko to działa, ponieważ klasa JSONArray jest obsługiwana przez prostą ArrayList, która jest już iterowalna. Wyobrażam sobie, że inne implementacje open source byłyby równie łatwe do zmiany.

Thunderforge
źródło
1
Co ciekawe, kiedyś implementacja JSON.org miała Iterator w klasie JSONArray, ale usunęli ją: github.com/douglascrockford/JSON-java/commit/ ...
vipw
@vipw Kiedyś wysłałem im e-mail o zaimplementowaniu Iterable, ale powiedzieli, że ostatecznie nie mogą, ponieważ złamałoby to kompatybilność z Javą 1.4. Być może dlatego został usunięty w zatwierdzeniu.
Thunderforge
3

W tablicach poszukaj:

JSONArray menuitemArray = popupObject.getJSONArray("menuitem"); 
Paul Burke
źródło
2

Używasz tego samego obiektu Cast dla każdego wpisu. W każdej iteracji po prostu zmieniłeś ten sam obiekt, zamiast tworzyć nowy.

Ten kod powinien to naprawić:

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
źródło
1

Podczas iteracji po tablicy JSON (org.json.JSONArray, wbudowana w system Android), uważaj na obiekty puste ; na przykład możesz otrzymać "null"zamiast łańcucha pustego .

Czek może wyglądać następująco:

s[i] = array.isNull(i) ? null : array.getString(i);
18446744073709551615
źródło