Itération de tableau JSON dans Android / Java

148

Je construis une application Android qui doit être téléchargée et synchronisée avec une base de données en ligne, j'envoie ma requête de l'application vers une page php qui renvoie les lignes pertinentes d'une base de données au format JSON.

quelqu'un peut-il me dire la meilleure façon d'itérer dans un tableau JSON?

Je reçois un tableau d'objets:

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

Quel est le morceau de code le plus simple que je pourrais utiliser pour accéder aux JSONObjects dans le tableau?

EDIT: maintenant que j'y pense, la méthode que j'ai utilisée pour itérer la boucle était:

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

Donc je suppose que j'avais été en quelque sorte capable de transformer le Json retourné en un tableau itératif. Des idées comment je pourrais y parvenir?

Je m'excuse pour mon vagabondage, mais je l'ai fait fonctionner à partir d'un exemple que j'ai trouvé sur le Web et je n'ai pas pu le trouver depuis.

Kevin Bradshaw
la source

Réponses:

67

Je l'ai fait de deux manières différentes,

1.) faire une carte

        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.) créer un JSONArray de noms

    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
la source
335

Je pense que ce code est court et clair:

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

C'est ce que tu cherchais?

vipw
la source
3
Sympa et simple! Fonctionne très bien!
Kervin Ramen
5
notez que si vous envoyez un "tableau" qui n'a pas de nombres consécutifs, vous devez utiliser JSONObject
max4ever
ouais c'est parfait mais bien qu'une grande quantité de données soit très lente à traiter :(
Ahmad Arslan
@ArslanAhmad Si vous avez une grande quantité de données, vous ne voulez pas construire le tableau d'objets json entier en mémoire. Utilisez plutôt une approche de type SAX. Voir ici: stackoverflow.com/questions/10657725/…
vipw
cela ne fonctionne pas pour moi. j'obtiens une exception JSON à cause du crochet "{" entourant l'objet?
filthy_wizard
7

Malheureusement, JSONArray ne prend pas en charge les foreachdéclarations, telles que:

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

Rêver
la source
il le fait, mais il renvoie un objet pas JSONObject
Erreur
3
La classe JSONArray n'implémente pas l'interface Iterable
Jorgesys
4

Quand j'ai essayé la suggestion de @ vipw, j'ai été confronté à cette exception: The method getJSONObject(int) is undefined for the type JSONArray

Cela a fonctionné pour moi à la place:

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.
la source
Pour Android, j'ai changé myJsonArray.size () en myJsonArray.length () à la place
Rishiraj Purohit
3

Si vous utilisez l' implémentation Java JSON.org , qui est open source, vous pouvez simplement faire en sorte que JSONArray implémente l' Iterableinterface et ajouter la méthode suivante à la classe:

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

Cela rendra toutes les instances de JSONArray itérables, ce qui signifie que la for (Object foo : bar)syntaxe fonctionnera désormais avec lui (notez que foo doit être un Object, car les JSONArrays n'ont pas de type déclaré). Tout cela fonctionne car la classe JSONArray est soutenue par une simple ArrayList, qui est déjà itérable. J'imagine que d'autres implémentations open source seraient tout aussi faciles à changer.

Thunderforge
la source
1
Ce qui est intéressant, c'est qu'à un moment donné, l'implémentation JSON.org avait un Iterator dans la classe JSONArray, mais ils l'ont supprimé: github.com/douglascrockford/JSON-java/commit/…
vipw
@vipw Je leur avais envoyé un e-mail à propos de l'implémentation d'Iterable, mais ils ont dit qu'en fin de compte, ils ne pouvaient pas car cela briserait la compatibilité avec Java 1.4. C'est peut-être pour cela qu'il a été supprimé dans le commit.
Thunderforge
3

Sur les tableaux, recherchez:

JSONArray menuitemArray = popupObject.getJSONArray("menuitem"); 
Paul Burke
la source
2

Vous utilisez le même objet Cast pour chaque entrée. À chaque itération, vous venez de modifier le même objet au lieu d'en créer un nouveau.

Ce code devrait le corriger:

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
la source
1

Lors de l'itération sur un tableau JSON (org.json.JSONArray, intégré à Android), faites attention aux objets nuls ; par exemple, vous pouvez obtenir "null"au lieu d'une chaîne nulle .

Un chèque peut ressembler à:

s[i] = array.isNull(i) ? null : array.getString(i);
18446744073709551615
la source