本文已授權公眾號「伯特說」原創首發。
在實際開發中,難免會與網絡數據打交道,這就涉及到 Json 數據字段分析、解析,轉換成 Java Bean 等相關內容。那么本文就圍繞這幾個點,為大家介紹幾個技巧、插件,提升開發效率。
下面開始正文。
1. 準備數據
首先,我們需要有數據,以我在聚合數據上申請的菜譜大全為例[只有免費的1000次,用完就沒了,請惜之],接口地址如下:
如果你發現上面的接口失效了,我備份了一份,訪問 并手動復制即可。
其實,你完全可以自己申請一個 key 來測試,把上面接口的 key 換成你申請的就可以了。
申請地址:https://www.juhe.cn/docs/api/id/46
2.直觀的查看數據
類似于上面的接口,在開發中,后臺同事給了接口,我們肯定要先看一眼,確認下是什么樣的數據格式。那怎么看呢?把上面的接口粘貼到瀏覽器的地址欄,回車:
臥槽,這亂七八糟的怎么看?
想必你和我一樣,第一反應是崩潰的。別著急,自有辦法。
使用 Chrome 瀏覽器的同學,可以借助 Json-handle
插件方面的查看 Json 數據:對JSON格式的內容進行瀏覽和編輯,以樹形圖樣式展現JSON文檔,并可實時編輯。
這是我用過的最好用的 Json 展示和編輯插件,如果有更好的,歡迎推薦。在 Chrome 商店中的地址如下:
https://chrome.google.com/webstore/detail/json-handle/iahnhfdhidomcpggpaimmmahffihkfnj?hl=zh-CN
裝好插件后,再次刷新剛才的 api 地址,神奇的一幕發生了:
是不是很清晰?展開、收起,想怎么看就怎么看。許多對 Json 數據結構不了解的童鞋,可以借這個插件學習分析 Json 結構,很直觀。
同時,其還具備其它同類插件沒有的功能,直接將光標放在圖片 URL 上,可以直接預覽圖片,GIF 也可以:
更多功能等你去探索,我們接著往后。
3.生成 Json 對應的 Java Bean
預覽返回的 Json 數據后,你可能已經迫不及待想要解析數據了。且慢,在此之前,我們還差一步:生成 Java Bean,也就是我們常說的實體對象,這樣才能將返回的 Json 數據轉化成內存中的對象使用。
一說到這,我們立馬頭大了,再次預覽上面的數據:
我們的核心是 result
對象,其包含了一個 data
數組,對應著10個菜譜對象;每個菜譜對象又包含若干屬性,有簡單的類似 id
,title
的字段,但也有 albums
,steps
這樣的復雜數組...
這樣的數據結構,其復雜程度應該不亞于實際開發中大多數場景了。但是,這豈能難倒我們?
要知道這是我精心挑選出來做示例的 API,沒有難度怎么有說服力。下面一起來秒殺它!
根據上面的分析,假設我們關心 result
所包含的數據,那么我們的 Bean 實體的數據結構最后大致是這樣的:
//result
public class CookRequestResult {
//result 包含的 data 數組,即若干菜譜
private List<DataBean> data;
//data 中每個菜譜對象
public static class DataBean {
//菜譜的 steps,即做菜時的若干步驟
private List<StepsBean> steps;
//每個步驟對象
public static class StepsBean {
}
}
}
上述拋開了基本類型字段,簡化后概括來說:
CookRequestResult
包含 DataBean
對象集合,DataBean
中又包含 StepsBean
對象集合。分別對應上面的 api 返回的 result
,data
和 steps
。
這樣一個數據結構,手寫起來,不僅麻煩,還容易出錯,如何是好?這就輪到本文的第二個插件 GsonFormat 登場了。
下面簡單說下從安裝到使用的過程:
- 首先,在 Android Studio 的插件中,搜索
GsonFormat
,安裝并重啟生效:
然后,新建一個空的實體類,命名
CookRequestResult
,表示菜譜請求返回的數據;接下來,在 Json-handle 中選中
result
節點,復制右側窗口的數據:
- 最后,打開新建的類,按快捷鍵
Alt + Insert
,調出 Generate 窗口,選擇剛才安裝的GsonFormat
,粘貼數據。點擊OK
并確認所有字段后,插件就會根據 Json 生成CookRequestResult
的字段(非基本類型的字段,會生成對應的內部靜態類),并生成對字段對應的 getter 和 setter 方法。
最后效果如下(粘貼代碼時為避免冗余,去除了 getter 和 setter 方法):
/**
* 菜譜請求數據
* Created by ruicbAndroid on 2017/7/23.
*/
public class CookRequestResult {
private String totalNum;
private String pn;
private String rn;
private List<DataBean> data;
public static class DataBean {
private String id;
private String title;
private String tags;
private String imtro;
private String ingredients;
private String burden;
private List<String> albums;
private List<StepsBean> steps;
public static class StepsBean {
private String img;
private String step;
}
}
}
很給力有木有。可以看出,GsonFormat 支持以內部靜態類的形式一層層嵌套對象,強大到超乎你想象(當然了,你也可以手動將內部類對象提出去)。
以上就是關于生成 Java Bean 的介紹,你應該自己試一試,我說再多都不如自己動手來的直接、形象。
4.解析 Json 數據
歷經千辛萬苦(有點夸張了,如果熟練的話,上面的操作也就幾分鐘的事),終于可以解析 Json 數據了。但是這一塊不是本文的重點,就一帶而過。
一般就是通過網絡請求數據,獲取數據,然后將數據映射為對應的 Bean。解析 Json 數據常用方式有二:
使用 Gson 或者 FastJson 等解析庫,具體用法就不展開了。
使用 SDK 中自帶的 JsonObject,JsonArray 等自行解析數據,這樣可以避免引入三方庫。
具體使用哪種方式看自己需求了,這塊沒有技巧可言,靠的是扎實的技術基礎。
5.序列化對象
至此,我們已經可以從容的應對 Json 的分析、生成 Java Bean 和解析 Json
數據,還差最后一步:序列化 Java Bean。
在開發中,我們難免需要在組件之間傳遞數據,比如從列表頁點擊進入詳情,此時通過 Intent 傳遞數據時就需要序列化對象。序列化對象的方式,一般有兩種:
- 實現 Serializable 接口;
- 實現 Parcelable,并重寫對應方法;
實現 Serializable 較為簡單,直接添加 implements 即可;
而實現 Parcelable 接口,則需要重寫相應的方法,指定你需要序列化及反序列化的字段,還是比較麻煩的。以上面的 DataBean
為例,實現 Parcelable 接口后會新增以下內容:
public static class DataBean implements Parcelable {
//省略已經貼過的代碼...
//以下是實現 Parcelable 接口需要新增的代碼
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.id);
dest.writeString(this.title);
dest.writeString(this.tags);
dest.writeString(this.imtro);
dest.writeString(this.ingredients);
dest.writeString(this.burden);
dest.writeStringList(this.albums);
dest.writeList(this.steps);
}
public DataBean() {
}
protected DataBean(Parcel in) {
this.id = in.readString();
this.title = in.readString();
this.tags = in.readString();
this.imtro = in.readString();
this.ingredients = in.readString();
this.burden = in.readString();
this.albums = in.createStringArrayList();
this.steps = new ArrayList<StepsBean>();
in.readList(this.steps, StepsBean.class.getClassLoader());
}
public static final Parcelable.Creator<DataBean> CREATOR = new Parcelable.Creator<DataBean>() {
@Override
public DataBean createFromParcel(Parcel source) {
return new DataBean(source);
}
@Override
public DataBean[] newArray(int size) {
return new DataBean[size];
}
};
}
這還沒完,因為 DataBean
包含了 StepsBean
,其不屬于基本數據類型,我們還需要讓 StepsBean
實現 Parcelable 接口并重寫相應的方法...
兩個方案,至于選哪個,看你自己。二者各有優勢:
- Serializable:簡單,實現個接口即可,但序列化、反序列化效率相對較低;
- Parcelable:序列化、反序列化效率更高,但實現起來復雜;
一想到 Parcelable 實現起來的復雜程度,我們懶癌又犯了,忍不住說服自己實現 Serializable,畢竟現在手機性能都不差,不差那點~~
但是,有些人懶癌比我們還嚴重,他們既考慮到性能問題,又希望自動生成實現 Parcelable 接口時需要寫的代碼。于是乎,對應的插件應運而生,一勞永逸。
在 Android Studio 搜索
Parcelable
關鍵字,安裝Android Parcelable code generator
插件并重啟讓插件生效;回到
CookRequestResult
類,將光標定到DataBean
內部類中;使用快捷鍵
Alt + Insert
調出Generate
窗口,選擇Parcelable
,確認需要序列化的字段后點擊 OK,搞定!
序列化的效果就是上面貼出的代碼,就不重復貼了。
最后,讓 StepsBean
也實現 Parcelable,異曲同工了啊。
收工,關電腦出去浪,不負好時光~
6.總結
至此,本文告一段落了。由于篇幅有限,許多細節沒有展開講,不過事無巨細,我把工具、思路拋出來,各位可以自行查閱、實踐。實踐過程中,有任何問題都可以留言提出。
就醬,周末愉快~ 有幫助就順手關注我的公眾號~