Gson是Google所提供的Java library用來處理Java物件與JSON字串之間的轉換
本篇將以YouBike開源資料為例實作
在Gson官方網站中,除了提供下載API的網址,也有詳細的User Guide與範例實作
Gson導入
使用Android Studio導入Gson,需要在build.gradle(Module:app)這邊設定
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
}
若使用別的編譯器,可以導入jar檔
可到這邊下載: jar
設定完成後即可使用Gson
Gson實作
筆者以 [Android] JSON觀念介紹 & 使用YouBike站點資料實作 為基礎,以Gson改寫JSON字串的分析
Gson改寫專案的全部內容可參考連結: Gson實作YouBike站點資料分析
原本的Bike類別是經由分析YouBike JSON資料內容,擷取出要顯示在RecyclerView的YouBike站點資訊
要用Gson,資料類別設計需要跟YouBike JSON資料架構一樣
比較快速的方法,可以將JSON字串貼到 jsonschema2pojo,網頁即可自動產生對應的Java類別
新的資料類別設計如下圖,由於類別成員眾多就不把set/get的方法列出來
為Station, Result, Fields, Records,Records類別為YouBikes的核心資料群
由於JSON資料裡的名稱常常看不出是表達什麼,需要參考open data的文件解釋
所以可以在類別成員前面加上@SerializedName("Original Name")
,類別成員及可自訂名字
像是Records裡的成員sna是代表YouBike站點名稱,從字面上很難看出來
用以下的方式即可改成後續程式維護較易的名稱
@SerializedName("sna")
private String name;
要將資料藉由RecyclerView顯示,需要設計兩個類別分別繼承RecyclerView.Adapter & RecyclerView.ViewHolder
前篇是用BikeAdapter & BikeHolder,由於資料類別重新設計,因此新做兩個類別分別為StationAdapter & StationHolder
新的類別跟原本類別的差異不大,主要在Adapter的成員不同,為了對應新的資料類別
如前篇所述,網路資料相關處理建議使用AsyncTask類別
在doInBackground
方法得到YouBike JSON字串,然後覆寫onPostExecute
方法解析JSON字串並藉由RecyclerView顯示
1. 首先建立一個Gson物件,gson
2. 指定型態為listType
3. 藉由fromJson方法將得到Station型態的物件
4. 最後經由set/get得到Records陣列
5. 利用for迴圈將YouBike站點資訊抽取出來建立新的Records物件,並放入records陣列中
6. 使用RecyclerView顯示YouBike站點資訊
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Gson gson = new Gson();
Type listType = new TypeToken<Station>(){}.getType();
Station station = gson.fromJson(result, listType);
Result stationResult = station.getResult();
Records[] records = stationResult.getRecords();
int index = 0;
for (Records record: records) {
String name = record.getName();
String address = record.getAddress();
String totalNumber = record.getTotalNumber();
String lendNumber = record.getLendNumber();
String returnNumber = record.getReturnNumber();
String latitude = record.getLatitude();
String longitude = record.getLongitude();
records[index] = new Records(name, address,
totalNumber, lendNumber,
returnNumber, latitude, longitude);
index++;
}
recycler.setAdapter(new StationAdapter(station));
}