Lặp lại mảng JSON trong Android / Java


148

Tôi đang xây dựng một ứng dụng Android cần tải xuống và đồng bộ hóa với cơ sở dữ liệu trực tuyến, tôi đang gửi truy vấn của mình từ ứng dụng đến trang php để trả về các hàng có liên quan từ cơ sở dữ liệu ở định dạng JSON.

ai đó có thể vui lòng cho tôi biết cách tốt nhất để lặp qua một mảng JSON không?

Tôi nhận được một loạt các đối tượng:

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

Đoạn mã đơn giản nhất tôi có thể sử dụng để truy cập JSONObjects trong mảng là gì?

EDIT: bây giờ tôi nghĩ về nó phương pháp tôi đã sử dụng để lặp lại vòng lặp là:

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

Vì vậy, tôi đoán rằng bằng cách nào đó tôi đã có thể biến Json trở lại thành mảng và lặp lại. Bất kỳ ý tưởng làm thế nào tôi có thể đạt được điều này?

Tôi xin lỗi vì sự mơ hồ của tôi nhưng tôi đã làm việc này từ một ví dụ tôi tìm thấy trên web và từ đó không thể tìm thấy nó.


Câu trả lời:


67

Tôi đã làm nó theo hai cách khác nhau,

1.) tạo bản đồ

        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.) tạo một JSONArray của tên

    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

Tôi nghĩ mã này ngắn và rõ ràng:

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ó phải đó là thứ bạn tìm?


3
Đẹp và đơn giản! Hoạt động tuyệt vời!
Kervin Ramen

5
lưu ý rằng nếu bạn gửi một "mảng" không có số liên tiếp, bạn phải sử dụng JSONObject
max4ever

vâng nó hoàn hảo nhưng trong khi lượng dữ liệu lớn thì việc xử lý rất chậm :(
Ahmad Arslan

@ArslanAhmad Nếu bạn có một lượng lớn dữ liệu, bạn không muốn xây dựng toàn bộ mảng đối tượng json trong bộ nhớ. Thay vào đó sử dụng một cách tiếp cận giống như SAX. Xem tại đây: stackoverflow.com/questions/10657725/ Lời
vipw

Điều này không làm việc cho tôi. tôi nhận được Ngoại lệ JSON vì dấu ngoặc "{" bao quanh đối tượng?
filthy_wizard

7

Thật không may, JSONArray không hỗ trợ foreachbáo cáo, như:

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


nó có, nhưng nó trả về đối tượng không phải JSONObject
Lỗi

3
Lớp JSONArray không triển khai giao diện Iterable
Jorgesys

4

Khi tôi thử đề xuất của @ vipw, tôi đã phải đối mặt với ngoại lệ này: The method getJSONObject(int) is undefined for the type JSONArray

Điều này làm việc cho tôi thay vào đó:

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

Đối với Android, tôi đã thay đổi myJsonArray.size () thành myJsonArray.length ()
Rishiraj Purohit

3

Nếu bạn đang sử dụng triển khai Java JSON.org , là nguồn mở, bạn có thể làm cho JSONArray triển khai Iterablegiao diện và thêm phương thức sau vào lớp:

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

Điều này sẽ làm cho tất cả các phiên bản của JSONArray có thể lặp lại, có nghĩa là for (Object foo : bar)cú pháp bây giờ sẽ hoạt động với nó (lưu ý rằng foo phải là một Object, bởi vì JSONArrays không có kiểu khai báo). Tất cả điều này hoạt động vì lớp JSONArray được hỗ trợ bởi một ArrayList đơn giản, đã được lặp lại. Tôi tưởng tượng rằng các triển khai nguồn mở khác sẽ dễ thay đổi như vậy.


1
Điều thú vị là tại một thời điểm, việc triển khai JSON.org có Iterator trong lớp JSONArray, nhưng họ đã xóa nó: github.com/douglascrockford/JSON-java/commit/
trộm

@vipw Tôi đã gửi email cho họ một lần về việc triển khai Iterable, nhưng họ nói rằng cuối cùng họ không thể vì nó sẽ phá vỡ tính tương thích với Java 1.4. Có lẽ đó là lý do tại sao nó đã được gỡ bỏ trong cam kết.
Thunderforge

3

Trên Mảng, tìm kiếm:

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

2

Bạn đang sử dụng cùng một đối tượng Cast cho mỗi mục nhập. Trên mỗi lần lặp, bạn chỉ cần thay đổi cùng một đối tượng thay vì tạo một đối tượng mới.

Mã này sẽ sửa nó:

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

Trong khi lặp qua một mảng JSON (org.json.JSONArray, được tích hợp vào Android), hãy coi chừng các đối tượng null ; ví dụ, bạn có thể nhận được "null"thay vì chuỗi null .

Một kiểm tra có thể trông giống như:

s[i] = array.isNull(i) ? null : array.getString(i);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.