Hướng dẫn xử lý JSON trong Android
Công ty Vĩnh Cửu tuyển dụng lập trình viên Java

1- JSON là gì?

JSON (JavaScript Object Notation) là một định dạng trao đổi dữ liệu dữ liệu (data exchange format). Nó lưu trữ các dữ liệu theo cặp khóa và giá trị. So với XML thì JSON đơn giản về dễ đọc hơn. 

Hãy xem một ví dụ đơn giản của JSON:
{
"name" : "Tran",
"address" : "Hai Duong, Vietnam",
"phones" : [0121111111, 012222222]
}
Các cặp key-value có thể lồng nhau:
{
  "id": 111 ,
  "name":"Microsoft",
  "websites": [
     "http://microsoft.com",
     "http://msn.com",
     "http://hotmail.com"
  ],
  "address":{
     "street":"1 Microsoft Way",
     "city":"Redmond"
  }
}
Trong Java có rất nhiều các thư viện mã nguồn mở giúp bạn thao tác với tài liệu JSON, chẳng hạn như:
  1. JSONP
  2. json.org
  3. Jackson
  4. Google GSON
  5. json-lib
  6. javax json
  7. json-simple
  8. json-smart
  9. flexjson
  10. fastjson
Android hỗ trợ sẵn thư viện để làm việc với JSON, bạn không cần phải khai báo bất cứ một thư viện nào khác. Trong tài liệu hướng dẫn này tôi sẽ hướng dẫn bạn làm việc với JSON sử dụng JSON API có sẵn trong hệ điều hành của Android.

2- JSON và Java Object

Hình minh họa dưới đây mô tả mối quan hệ giữa JSON và class Java.

3- Tạo nhanh một Project để làm việc với JSON

Tôi tạo nhanh một project để làm việc với JSON thông qua các ví dụ, tạo project có tên JSONTutorial.
Tạo thư mục raw:
Tôi tạo thêm một vài file json trong thư mục 'raw', các file này sẽ tham gia vào một các ví dụ trong tài liệu này.

Các nguồn cung cấp dữ liệu JSON có thể từ file hoặc URL,... Ở cuối tài liệu bạn có thể xem ví dụ lấy dữ liệu JSON từ URL, phân tích và hiển thị trên một ứng dụng Android.

  • company.json
{
  "id": 111 ,
  "name":"Microsoft",
  "websites": [
     "http://microsoft.com",
     "http://msn.com",
     "http://hotmail.com"
  ],
  "address":{
     "street":"1 Microsoft Way",
     "city":"Redmond"
  }
}
Thiết kế activity_main.xml:
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="org.o7planning.jsontutorial.MainActivity">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="300dp"
        android:id="@+id/editText"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Run Example"
        android:id="@+id/button"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="37dp"
        android:onClick="runExample" />
    
</RelativeLayout>

4- Java Beans classes

Một số class tham gia vào các ví dụ:
  • Address.java
package org.o7planning.jsontutorial.beans;


public class Address {

    private String street;
    private String city;

    public Address() {

    }

    public Address(String street, String city) {
        this.street = street;
        this.city = city;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return street + ", " + city;
    }

}
  • Company.java
package org.o7planning.jsontutorial.beans;

public class Company {

    private int id;
    private String name;
    private String[] websites;
    private Address address;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String[] getWebsites() {
        return websites;
    }

    public void setWebsites(String[] websites) {
        this.websites = websites;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        sb.append("\n id:" + this.id);
        sb.append("\n name:" + this.name);
        if (this.websites != null) {
            sb.append("\n website: ");
            for (String website : this.websites) {
                sb.append(website + ", ");
            }
        }
        if (this.address != null) {
            sb.append("\n address:" + this.address.toString());
        }
        return sb.toString();
    }

}

5- Ví dụ đọc dữ liệu JSON chuyển thành đối tượng Java

Trong ví dụ này chúng ta sẽ đọc file dữ liệu JSON và chuyển nó thành đối tượng Java.
  • ReadJSONExample.java
package org.o7planning.jsontutorial.json;

import android.content.Context;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.o7planning.jsontutorial.R;
import org.o7planning.jsontutorial.beans.Address;
import org.o7planning.jsontutorial.beans.Company;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


public class ReadJSONExample {

    // Đọc file company.json và chuyển thành đối tượng java.
    public static Company readCompanyJSONFile(Context context) throws IOException,JSONException {

        // Đọc nội dung text của file company.json
        String jsonText = readText(context, R.raw.company);

        // Đối tượng JSONObject gốc mô tả toàn bộ tài liệu JSON.
        JSONObject jsonRoot = new JSONObject(jsonText);


        int id= jsonRoot.getInt("id");
        String name = jsonRoot.getString("name");

        JSONArray jsonArray = jsonRoot.getJSONArray("websites");
        String[] websites = new String[jsonArray.length()];

        for(int i=0;i < jsonArray.length();i++) {
            websites[i] = jsonArray.getString(i);
        }

        JSONObject jsonAddress = jsonRoot.getJSONObject("address");
        String street = jsonAddress.getString("street");
        String city = jsonAddress.getString("city");
        Address address= new Address(street, city);

        Company company = new Company();
        company.setId(id);
        company.setName(name);
        company.setAddress(address);
        company.setWebsites(websites);
        return company;
    }


    // Đọc nội dung text của một file nguồn.
    private static String readText(Context context, int resId) throws IOException {
        InputStream is = context.getResources().openRawResource(resId);
        BufferedReader br= new BufferedReader(new InputStreamReader(is));
        StringBuilder sb= new StringBuilder();
        String s= null;
        while((  s = br.readLine())!=null) {
            sb.append(s);
            sb.append("\n");
        }
        return sb.toString();
    }

}
  • MainActivity.java
package org.o7planning.jsontutorial;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import org.o7planning.jsontutorial.beans.Company;
import org.o7planning.jsontutorial.json.ReadJSONExample;

public class MainActivity extends AppCompatActivity {

    private EditText outputText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        outputText = (EditText)this.findViewById(R.id.editText);
    }


    // Phương thức được gọi khi người dùng nhấn vào Button
    public void runExample(View view)  {
        try {
            // Đọc file: res/raw/company.json và trả về đối tượng Company.
            Company company = ReadJSONExample.readCompanyJSONFile(this);

            outputText.setText(company.toString());
        } catch(Exception e)  {
            outputText.setText(e.getMessage());
            e.printStackTrace();
        }
    }

}
Chạy ví dụ:

6- Ví dụ chuyển đối tượng Java thành dữ liệu JSON

Ví dụ sau chuyển một đối tượng Java thành một dữ liệu JSON.
  • JsonWriterExample.java
package org.o7planning.jsontutorial.json;

import android.util.JsonWriter;

import org.o7planning.jsontutorial.beans.Address;
import org.o7planning.jsontutorial.beans.Company;
import java.io.IOException;
import java.io.Writer;

public class JsonWriterExample {

    // Ghi một đối tượng Java thành dữ liệu JSON vào Writer.
    public static void writeJsonStream(Writer output, Company company ) throws IOException {
        JsonWriter jsonWriter = new JsonWriter(output);

        jsonWriter.beginObject();// begin root

        jsonWriter.name("id").value(company.getId());
        jsonWriter.name("name").value(company.getName());

        String[] websites= company.getWebsites();

        // "websites": [ ....]
        jsonWriter.name("websites").beginArray(); // begin websites
        for(String website: websites) {
            jsonWriter.value(website);
        }
        jsonWriter.endArray();// end websites

        // "address": { ... }
        jsonWriter.name("address").beginObject(); // begin address
        jsonWriter.name("street").value(company.getAddress().getStreet());
        jsonWriter.name("city").value(company.getAddress().getCity());
        jsonWriter.endObject();// end address

        // end root
        jsonWriter.endObject();
    }


    public static Company createCompany() {

        Company company = new Company();
        company.setId(123);
        company.setName("Apple");

        String[] websites = { "http://apple.com", "https://jobs.apple.com" };
        company.setWebsites(websites);

        Address address = new Address();
        address.setCity("Cupertino");
        address.setStreet("1 Infinite Loop");

        company.setAddress(address);

        return company;
    }

}
  • MainActivity.java (2)
package org.o7planning.jsontutorial;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import org.o7planning.jsontutorial.beans.Company;
import org.o7planning.jsontutorial.json.JsonWriterExample;

import java.io.StringWriter;

public class MainActivity extends AppCompatActivity {

    private EditText outputText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        outputText = (EditText)this.findViewById(R.id.editText);
    }


    // Phương thức được gọi khi người dùng nhấn vào Button
    public void runExample(View view)  {
        try {
            StringWriter output = new StringWriter();

            Company company = JsonWriterExample.createCompany();

            // Chuyển đối tượng Java 'company' thành dữ liệu JSON và ghi vào Writer output.
            JsonWriterExample.writeJsonStream(output, company);

            String jsonText = output.toString();

            outputText.setText(jsonText);
        } catch(Exception e)  {
            outputText.setText(e.getMessage());
            e.printStackTrace();
        }
    }
}
Chạy ứng dụng:

7- Đọc JSON từ URL

  • TODO