Iterazione di array JSON in Android / Java


148

Sto creando un'app Android che deve essere scaricata e sincronizzata con un database online, invio la mia query dall'app a una pagina php che restituisce le righe pertinenti da un database in formato JSON.

qualcuno può dirmi il modo migliore per iterare attraverso un array JSON?

Ricevo una serie di oggetti:

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

Qual è il codice più semplice che potrei usare per accedere a JSONObjects nell'array?

EDIT: ora che ci penso, il metodo che ho usato per ripetere il ciclo era:

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

Quindi immagino di aver potuto in qualche modo trasformare il Json restituito in un array iterabile. Qualche idea su come potrei raggiungere questo obiettivo?

Mi scuso per la mia vaghezza ma ho avuto questo lavoro da un esempio che ho trovato sul web e da allora non sono riuscito a trovarlo.


Risposte:


67

L'ho fatto in due modi diversi,

1.) fare una mappa

        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.) crea un JSONArray di nomi

    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

Penso che questo codice sia breve e chiaro:

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

È quello che stavi cercando?


3
Bello e semplice! Funziona alla grande!
Kervin Ramen,

5
si noti che se si invia un "array" che non ha numeri consecutivi, è necessario utilizzare JSONObject
max4ever

sì, è perfetto, ma mentre una grande quantità di dati è molto lenta nell'elaborazione :(
Ahmad Arslan

@ArslanAhmad Se si dispone di una grande quantità di dati, non si desidera costruire l'intero array di oggetti json in memoria. Utilizzare invece un approccio simile a SAX. Vedi qui: stackoverflow.com/questions/10657725/...
vipw

questo non funziona per me. ottengo un'eccezione JSON a causa della parentesi "{" che circonda l'oggetto?
filthy_wizard,

7

Sfortunatamente, JSONArray non supporta le foreachdichiarazioni, come:

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


lo fa, ma restituisce l'oggetto non JSONObject
Errore

3
La classe JSONArray non implementa l'interfaccia
Iterable

4

Quando ho provato il suggerimento di @ vipw, ho dovuto affrontare questa eccezione: The method getJSONObject(int) is undefined for the type JSONArray

Questo ha funzionato per me invece:

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...
}

Per Android, ho invece cambiato myJsonArray.size () in myJsonArray.length ()
Rishiraj Purohit,

3

Se stai usando l' implementazione Java di JSON.org , che è open source, puoi semplicemente fare in modo che JSONArray attui l' Iterableinterfaccia e aggiunga il seguente metodo alla classe:

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

Ciò renderà iterabili tutte le istanze di JSONArray, il che significa che la for (Object foo : bar)sintassi ora funzionerà con esso (si noti che foo deve essere un oggetto, poiché JSONArrays non ha un tipo dichiarato). Tutto questo funziona perché la classe JSONArray è supportata da una semplice ArrayList, che è già iterabile. Immagino che altre implementazioni open source sarebbero altrettanto facili da modificare.


1
La cosa interessante è che un tempo l'implementazione di JSON.org aveva un Iteratore nella classe JSONArray, ma l'hanno rimosso: github.com/douglascrockford/JSON-java/commit/…
vipw

@vipw Una volta li avevo spediti via e-mail sull'implementazione di Iterable, ma hanno detto che alla fine non potevano farlo perché avrebbe rotto la compatibilità con Java 1.4. Forse è per questo che è stato rimosso nel commit.
Thunderforge

3

Su array, cerca:

JSONArray menuitemArray = popupObject.getJSONArray("menuitem"); 

2

Stai usando lo stesso oggetto Cast per ogni voce. Ad ogni iterazione hai appena cambiato lo stesso oggetto invece di crearne uno nuovo.

Questo codice dovrebbe risolverlo:

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;

1

Durante l'iterazione su un array JSON (org.json.JSONArray, integrato in Android), fai attenzione agli oggetti null ; ad esempio, è possibile ottenere "null"anziché una stringa nulla .

Un assegno può apparire come:

s[i] = array.isNull(i) ? null : array.getString(i);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.