Làm việc với Gson trong android

CHào, lại tới ngày viết viblo rồi. Chưa nghĩ ra được cái gì để viết, tiện dự án mình đang làm có đang dùng Gson nên mình cũng giới thiệu luôn cho các bạn chưa biết nó là gì?

1. Gson là gì?

Gson là một thư viện java cho phép người sử dụng có thể chuyển đổi từ một đối tượng Java sang JSON và cũng có thể chuyển đổi từ một đối tượng JSON sang java.Gson có thể làm việc với đối tượng java tùy ý bao gồm các đối tượng tồn tại sẵn mà bạn không có source-code của chúng.

2. Ví dụ

Để biết rõ hơn nó làm việc thế nào chúng ta cùng làm một ví dụ đơn giản. Tạo một project và add file Gson jar vào project. Để minh hoạ việc chuyển đổi JSON chúng ta sẽ dùng một API sau: https://ajax.googleapis.com/ajax/services/feed/find?v=1.0&q=Official Google Blogs'

Url trên sẽ trả về một chuỗi json và chúng ta sẽ dùng Gson để xử lý nó.

Trước tiên design cho file activity_mail.xml:

<LinearLayout 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:orientation="vertical" >

    <TextView
        android:id="@+id/query"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/list"
            android:layout_width="wrap_content"
            android:layout_height="300dp"
            android:text="@string/hello_world" />
    </ScrollView>

</LinearLayout>

File AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.framgia.gsonresearch"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Tạo một class SearchResponse.java tương ứng với chuỗi JSON trả về:

package com.framgia.json.model;

import java.util.List;

public class SearchResponse {
    public List<Result> entries;
    public String query;
    public SearchResponse responseData;
}

Như vậy so với chuỗi json trả về ta sẽ có được giá trị responseData, query và entries. Với mỗi item trong entries ta lại tạo một đối tượng java tương ứng với từng item trong list json đó. ở đây tôi tạo class Result.java với các @SerializedName tương ứng với các field của item trong entries.

package com.framgia.json.model;

import com.google.gson.annotations.SerializedName;

public class Result {
    @SerializedName("url")
    public String url;
    @SerializedName("title")
    public String title;
    @SerializedName("contentSnippet")
    public String contentSnippet;
    @SerializedName("link")
    public String link;
}

Cuối cùng sẽ là class quan trọng nhất. MainActivity.java.

private final String URL =
        "https://ajax.googleapis.com/ajax/services/feed/find?v=1.0&q=Official%20Google%20Blogs%27";

Url trả về chuỗi json.

Method find các TextView trong layout mục đích để hiển thị các kết quả convert JSON và đối tượng Java.

private void findView(){
        query = (TextView)findViewById(R.id.query);
        list = (TextView)findViewById(R.id.list);
    }

Method thực hiện việc request và trả về data dưới dạng chuỗi JSON từ API trên:

public static String getJsonFromServer(String url) throws IOException {

        BufferedReader inputStream = null;

        URL jsonUrl = new URL(url);
        URLConnection dc = jsonUrl.openConnection();

        dc.setConnectTimeout(5000);
        dc.setReadTimeout(5000);

        inputStream = new BufferedReader(new InputStreamReader(
                dc.getInputStream()));
        // read the JSON results into a string
        String jsonResult = inputStream.readLine();
        return jsonResult;
    }

Sau khi có được JSON data ta tiến hành chuyển đối từ JSON sang đối tượng java sử dụng Gson:

Gson gson = new Gson();
 final SearchResponse response = gson.fromJson(data, SearchResponse.class);
 Log.i("FRAMGIA", "Minh họa chuyển từ JSON sang đối tượng Java: ");
 Log.i("FRAMGIA", response.responseData.query+"");

Và chuyển từ đối tượng java sang JSON:

final List<Result> results = response.responseData.entries;
if(results == null) return;
Log.i("FRAMGIA", "Minh họa chuyển từ đối tượng Java sang JSON: ");
Log.i("FRAMGIA", new Gson().toJson(results));

Cả class MainActivity.java sau khi hoàn thành sẽ như sau:

package com.framgia.gsonresearch;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

import com.framgia.json.model.Result;
import com.framgia.json.model.SearchResponse;
import com.google.gson.Gson;

public class MainActivity extends Activity {
    private final String URL =
        "https://ajax.googleapis.com/ajax/services/feed/find?v=1.0&q=Official%20Google%20Blogs%27";
    private TextView query;
    private TextView list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findView();
        LongOperation.execute(new Runnable() {
            @Override
            public void run() {
                String data;
                try {
                    data = getJsonFromServer(URL);
                    Gson gson = new Gson();
                    final SearchResponse response = gson.fromJson(data, SearchResponse.class);
                    Log.i("FRAMGIA", "Minh họa chuyển từ JSON sang đối tượng Java: ");
                    Log.i("FRAMGIA", response.responseData.query+"");
                    final List<Result> results = response.responseData.entries;
                    if(results == null) return;
                    Log.i("FRAMGIA", "Minh họa chuyển từ đối tượng Java sang JSON: ");
                    Log.i("FRAMGIA", new Gson().toJson(results));

                    runOnUiThread(new Runnable() {
                        public void run() {
                            query.setText("JSON->Java Object: "+response.responseData.query);
                            list.setText("Java Object->JSON: "+new Gson().toJson(results));
                        }
                    });
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }

    private void findView(){
        query = (TextView)findViewById(R.id.query);
        list = (TextView)findViewById(R.id.list);
    }

    public static String getJsonFromServer(String url) throws IOException {

        BufferedReader inputStream = null;

        URL jsonUrl = new URL(url);
        URLConnection dc = jsonUrl.openConnection();

        dc.setConnectTimeout(5000);
        dc.setReadTimeout(5000);

        inputStream = new BufferedReader(new InputStreamReader(
                dc.getInputStream()));
        // read the JSON results into a string
        String jsonResult = inputStream.readLine();
        return jsonResult;
    }

  private class LongOperation extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        return null;
    }
  }
}

3. Tổng kết

Chúng ta đã đi xong ví dụ, từ ví dụ trên cho thấy rằng việc dùng Gson rất dễ dàng, không tốn công parse và cũng giúp chúng ta đỡ nhầm lẫn hơn khi parse trực tiếp từ JSON sang java. Đặc biệt là khi làm việc với những chuỗi JSON có rất nhiều trường.

Dưới đây là link download APK, bạn có thể dùng thử: https://drive.google.com/file/d/0B7td9WR1ZtQ0aWxuS3JLSFIyVVE/view?usp=sharing