Iteração de matriz JSON no Android / Java

148

Estou criando um aplicativo Android que precisa baixar e sincronizar com um banco de dados online. Estou enviando minha consulta do aplicativo para uma página php que retorna as linhas relevantes de um banco de dados no formato JSON.

alguém pode me dizer a melhor maneira de iterar através de uma matriz JSON?

Eu recebo uma matriz de objetos:

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

Qual é o trecho de código mais simples que eu poderia usar para acessar os JSONObjects na matriz?

EDIT: agora que penso nisso, o método usado para iterar o loop foi:

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

Então, acho que consegui transformar o Json retornado em um array iterável. Alguma idéia de como eu poderia conseguir isso?

Peço desculpas pela minha imprecisão, mas tive esse trabalho a partir de um exemplo que encontrei na web e, desde então, não consegui encontrá-lo.

Kevin Bradshaw
fonte

Respostas:

67

Eu fiz isso de duas maneiras diferentes,

1.) faça um mapa

        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.) faça um JSONArray de nomes

    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
fonte
335

Eu acho que esse código é curto e claro:

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

É isso que você estava procurando?

vipw
fonte
3
Agradável e simples! Funciona bem!
Kervin Ramen
5
Note que se você enviar um "array" que não tem números consecutivos, você tem que usar JSONObject
max4ever
sim, perfeito, mas enquanto grande quantidade de dados a ser muito lento no processamento :(
Ahmad Arslan
@ArslanAhmad Se você possui uma grande quantidade de dados, não deseja construir toda a matriz de objetos json na memória. Em vez disso, use uma abordagem semelhante ao SAX. Veja aqui: stackoverflow.com/questions/10657725/…
vipw
isso não funciona para mim. eu recebo uma exceção JSON por causa do colchete "{" ao redor do objeto?
Filthy_wizard # 3/15
7

Infelizmente, JSONArray não suporta foreachdeclarações, como:

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

Sonhe
fonte
sim, mas retorna objeto não JSONObject
Erro
3
Classe JSONArray não implementa interface de Iterable
Jorgesys
4

Quando tentei a sugestão do @ vipw, me deparei com esta exceção: The method getJSONObject(int) is undefined for the type JSONArray

Isso funcionou para mim:

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.
fonte
Para android, eu mudei myJsonArray.size () para myJsonArray.length () em vez
Rishiraj Purohit
3

Se você estiver usando a implementação Java JSON.org , que é de código aberto, basta fazer o JSONArray implementar a Iterableinterface e adicionar o seguinte método à classe:

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

Isso tornará todas as instâncias do JSONArray iteráveis, o que significa que a for (Object foo : bar)sintaxe agora funcionará com ele (observe que foo precisa ser um objeto, porque JSONArrays não tem um tipo declarado). Tudo isso funciona porque a classe JSONArray é apoiada por um ArrayList simples, que já é iterável. Eu imagino que outras implementações de código aberto sejam tão fáceis de mudar.

Forja do Trovão
fonte
1
O interessante é que ao mesmo tempo a implementação do JSON.org tinha um Iterator na classe JSONArray, mas eles o removeram: github.com/douglascrockford/JSON-java/commit/…
vipw
@vipw Eu os enviei um e-mail uma vez sobre a implementação do Iterable, mas eles disseram que, em última análise, não podiam, porque isso quebraria a compatibilidade com o Java 1.4. Talvez tenha sido por isso que foi removido no commit.
Thunderforge
3

Em matrizes, procure:

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

Você está usando o mesmo objeto Cast para todas as entradas. Em cada iteração, você acabou de alterar o mesmo objeto, criando um novo.

Este código deve corrigi-lo:

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
fonte
1

Enquanto itera sobre uma matriz JSON (org.json.JSONArray, embutida no Android), cuidado com objetos nulos ; por exemplo, você pode obter em "null"vez de um nulo sequência .

Uma verificação pode parecer com:

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