[Android] JSON觀念介紹 & 使用YouBike站點資料實作

JSON(JavaScript Object Notation),一種基於JavaScrip表示法且用來傳輸由屬性值或者序列性的值組成的資料物件。

JSON由於它的特性,需多開源資料都支援JSON格式的表示。

 

JSON格式

JSON格式的詳細資料可以參考這個網站

Introduction JSON

 

物件 (Object)

以大括號包含資料,一個大括號為一個物件

裡面的資料成對表示,每組資料會有一個名稱和數值,類似Java中Map類別的概念

資料組和資料組之間以逗號分開

{name1: value1, name2: value2}

 

陣列 (Array)

以中括號包含資料,一個中括號代表一個陣列

資料與資料間以逗號分隔

[value1, value2, value3]

而資料的形式可以為string, number, object, array, true, false, null

利用物件和陣列的搭配可以使JSON的資料表示更多樣化

 

YouBike JSON資料分析

新北市公共自行車租賃系統(YouBike)的政府開源資料為例

得到JSON資料如以下所示

從這樣的資料外觀很難分析整體的資料架構,可以利用JSON beautify關鍵字找到很多線上工具將資料整理成易讀的格式

筆者使用 JSON Formatter & Validator,可將資料用以下的方式顯示

並且可用減號(-)把資料集收起來,對於JSON資料的分析會更清楚,更好設計相應的類別

觀察架構可以知道我們需要資料對應名稱為records

"records":[{name1, value1}, {name2, value2}, {name3, value3}]

records所對應的資料為一個陣列,陣列裡的元素為物件,每個物件裡包裹的就是我們所要的資料

而records資料組被包在result資料組中,利用這些關係可以用JSON相應API解析

 

Android實作

可參考筆者的另一篇文章,有更詳細的專案實作介紹

[Android] 使用RecyclerView顯示新北市YouBike站點資料

 

Android Studio內建有JSON API,若不是使用Android實作,像是用IntelliJ, NetBeans, Eclipse等

必須另外導入jar檔,可以到以下連結下載

JSON Java Jar下載

JSON Java API文件

 

由於網路資料相關處理較為耗時,使用覆寫AsyncTask類別中的方法doInBackground在背景處理

連線到YoubBike站點資料,並且存取成String資料型態

@Override
protected String doInBackground(String... params) {
    StringBuffer json = new StringBuffer();

    try {
        URL url = new URL(params[0]);
        // params[0] = "http://data.ntpc.gov.tw/api/v1/rest/datastore/382000000A-000352-001"
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        InputStream is = connection.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line = br.readLine();
        while (line != null) {
            json.append(line);
            line = br.readLine();
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

    return json.toString();
}

 

覆寫AsyncTask類別中的方法onPostExecute,處理在doInBackground得到的String型態JSON資料

整包JSON資料為一個物件,這邊設定為jonObject

而result資料組的數值為一個物件,因此利用getJSONObject將result的物件從jonObject提取出來

JSONObject resultObj = jonObject.getJSONObject("result")

而records資料組的數值為陣列,使用getJSONArray將records的陣列從resultObj提取出來

JSONArray recordArray = resultObj.getJSONArray("records")

 

每個YouBike站點資訊被包裹成物件放在陣列recordArray

利用for迴圈將每個站點資訊提取出來放在設計的BIke物件裡

最後得到Bike集合,再將Bike集合利用RecyclerView的方式顯示出來

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);

    JSONObject jonObject = null;
    List<Bike> bikes = new ArrayList<>();

    try {
        jonObject = new JSONObject(result.toString());
        JSONObject resultObj = jonObject.getJSONObject("result");
        JSONArray recordArray = resultObj.getJSONArray("records");

        for (int i = 0; i < recordArray.length(); i++) {
            JSONObject object = recordArray.getJSONObject(i);
            String name = object.getString("sna");
            String address = object.getString("ar");
            String totalNumber = object.getString("tot");
            String lendNumber = object.getString("sbi");
            String returnNumber = object.getString("bemp");
            String latitude = object.getString("lat");
            String longitude = object.getString("lng");
            bikes.add(new Bike(name, address, totalNumber,
                    lendNumber, returnNumber, latitude, longitude));
            Log.d(TAG, "AsyncTask onPostExecute: " +
                    name + address+ totalNumber +
                    lendNumber + returnNumber +
                    latitude + longitude);
        }

        recycler.setAdapter(new BikeAdapter(bikes));


    } catch (JSONException e) {
        e.printStackTrace();
    }

}