前言:迷茫,本就是青春該有的樣子 ,但不要讓未來的你,討厭現(xiàn)在的自己
json:一種輕量級的數(shù)據(jù)交換格式,具有良好的可讀和便于快速編寫的特性。業(yè)內(nèi)主流技術(shù)為其提供了完整的解決方案(有點類似于正則表達式 ,獲得了當今大部分語言的支持),從而可以在不同平臺間進行數(shù)據(jù)交換。JSON采用兼容性很高的文本格式,同時也具備類似于C語言體系的行為。
Android交互數(shù)據(jù)主要有兩種方式:Json和Xml,Xml格式的數(shù)據(jù)量要比Json格式略大,為了節(jié)省流量,減輕服務(wù)器壓力,目前絕大多數(shù)公司都使用Json交互。
目錄
1:使用原生方式解析Json] (使用原生方式解析Json)
2:Gson框架的使用] (Gson框架的使用)
3:插件GsonFormat快速實現(xiàn)JavaBean (插件GsonFormat快速實現(xiàn)JavaBean)
一、使用原生方式解析Json
Json主要通過"{ }" 和 "[ ]" 包裹數(shù)據(jù),"{ }"里面存放key-value鍵值對, "[ ]" 里存放數(shù)組。
標準的Json格式key必須用雙引號。 下面都是Json:
{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}
[{"name" : "jack", "age" : 10},{"name" : "rose", "age" : 11}]
要想從JSON中挖掘出具體數(shù)據(jù),得對JSON進行解析。分別來看看三個不同的Json是如何解析的:
public void parseJson1(){
String json1="{\"name\" : \"jack\", \"age\" : 10}";
try {
//把要解析的json通過構(gòu)造方法告訴JSONObject
JSONObject jsonObject=new JSONObject(json1);
// 獲取name
String name=jsonObject.getString("name");
int age=jsonObject.getInt("age");
Log.i("ParserJsonActivity","name:"+name);
Log.i("ParserJsonActivity","age:"+age);
} catch (JSONException e) {
e.printStackTrace();
}
}
public void parseJson2(){
String json2="{\"names\" : [\"jack\", \"rose\", \"jim\"]}";
try {
//把要解析的json通過構(gòu)造方法告訴JSONObject
JSONObject jsonObject=new JSONObject(json2);
//names對應(yīng)的 JsonArray
JSONArray jsonArray=jsonObject.getJSONArray("names");
//遍歷JSONArray
for(int i=0;i<jsonArray.length();i++){
Log.i("ParserJsonActivity","name"+i+":"+jsonArray.getString(i));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void parseJson3(){
String json3="[{\"name\" : \"jack\", \"age\" : 10},{\"name\" : \"rose\", \"age\" : 11}]";
try {
//把要解析的json通過構(gòu)造方法告訴JSONArray
JSONArray jsonArray=new JSONArray(json3);
//遍歷JSONArray
for(int i=0;i<jsonArray.length();i++){
//根據(jù)i的位置獲取JSONObject
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.getString("name");
int age=jsonObject.getInt("age");
Log.i("ParserJsonActivity","name"+i+":"+name);
Log.i("ParserJsonActivity","age"+i+":"+age);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
上面的代碼,主要使用了JSONObject和JSONArray。
當碰到 “{ }”時用JSONObject解析,遇到“[ ]”時用JSONArray解析。
想要的數(shù)據(jù)全部都獲取到了。
二 、Gson框架的使用
如果你認為使用JSONObject和JSONArray來解析JSON數(shù)據(jù)已經(jīng)非常簡單了,那你就容易太滿足了。早就有框架可以使用了。
常見的框架有 Gson,FastJSON等等,他們都各有優(yōu)缺點,但是總體區(qū)別不大。
GSON方式
原理:基于事件驅(qū)動
優(yōu)點:解析方法簡單、解析效率高、占存少、靈活性高
使用情境:適用于需要處理大型 JSON文檔、JSON文檔結(jié)構(gòu)復雜的場合
Jackson方式
原理:基于事件驅(qū)動
優(yōu)點:解析效率最高、在數(shù)據(jù)量大的情況優(yōu)勢尤為明顯、占存少
缺點:必須完全解析文檔,如果要按需解析的話可以拆分Json來讀取,操作和解析方法復雜;
使用情境: 適用于需要處理超大型JSON文檔、不需要對JSON文檔進行按需解析、性能要求較高的場合
我一直用GSON方式解析,使用起來比較簡單。
首先在app/build.gradle中添加依賴。
dependencies {
...
compile 'com.google.code.gson:gson:2.6.2'
}
Gson是基于事件驅(qū)動,根據(jù)所需要取的數(shù)據(jù)通過建立一個對應(yīng)于JSON數(shù)據(jù)的JavaBean類就可以通過簡單的操作解析出所需JSON數(shù)據(jù)。
步驟1:創(chuàng)建一個與JSON數(shù)據(jù)對應(yīng)的JavaBean類(用作存儲需要解析的數(shù)據(jù))
GSON解析的關(guān)鍵是重點是要根據(jù)json數(shù)據(jù)里面的結(jié)構(gòu)寫出一個對應(yīng)的javaBean,規(guī)則是:
JSON的大括號對應(yīng)一個對象,對象里面有key和value(值)。在JavaBean里面的類屬性要和key同名;
JSON的方括號對應(yīng)一個數(shù)組,所以在JavaBeanBean里面對應(yīng)的也是數(shù)組或者集合,數(shù)據(jù)里面可以有值或者對象;
如果數(shù)組里面只有值沒有key,就說明它只是一個純數(shù)組,如果里面有值有key,則說明是對象數(shù)組。純數(shù)組對應(yīng)JavaBean里面的數(shù)組類型,對象數(shù)組要在Bean里面建立一個內(nèi)部類,類屬性就是對應(yīng)的對象里面的key,建立了之后要創(chuàng)建一個這個內(nèi)部類的對象,名字對應(yīng)數(shù)組名;
對象里面嵌套對象時候,也要建立一個內(nèi)部類,和對象數(shù)組一樣,這個內(nèi)部類對象的名字就是父對象的key。
注意:JavaBean類里的屬性不一定要全部和JSON數(shù)據(jù)里的所有key相同,可以按需取數(shù)據(jù),也就是你想要哪種數(shù)據(jù),就把對應(yīng)的key屬性寫出來,注意名字一定要對應(yīng)。
接下來,我們來看下下面兩條JSON數(shù)據(jù)按照上面的規(guī)則應(yīng)該何如生成JavaBean對象。
{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}
第一個:
/**
* {"name" : "jack", "age" : 10}
*/
public class Person1 {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
第二個:
/**
* {"names" : ["jack", "rose", "jim"]}
*/
public class Person2 {
private List<String> names;
public List<String> getNames() {
return names;
}
public void setNames(List<String> names) {
this.names = names;
}
}
再來看看使用如何Gson解析:
主要方法為:fromJson()
public void useGsonParser1(){
String json1="{\"name\" : \"jack\", \"age\" : 10}";
Gson gson=new Gson();
//把json數(shù)據(jù)解析成Person1對象
Person1 person1 = gson.fromJson(json1, Person1.class);
Log.i("UseGsonActivity","name:"+person1.getName());
Log.i("UseGsonActivity","age:"+person1.getAge());
}
public void useGsonParser2(){
String json2="{\"names\" : [\"jack\", \"rose\", \"jim\"]}";
Gson gson=new Gson();
Person2 person2=gson.fromJson(json2,Person2.class);
List<String> names = person2.getNames();
for(int i=0;i<names.size();i++){
Log.i("UseGsonActivity","name"+i+":"+names.get(i));
}
}
細心的同學會發(fā)現(xiàn),之前使用JSONObject和JSONArray解析了3條數(shù)據(jù),而我們并沒有使用GSON解析最后一條。
[{"name" : "jack", "age" : 10},{"name" : "rose", "age" : 11}]
最后一條比較特殊,是以"[ ]"開頭,我們知道因為大括號{ } 代表的是對象,中括號[]代表的是集合或者數(shù)組,所以javaBean直接使用Person1就行了,只不過返回的是一個集合或者數(shù)組。我們需要借助TypeToken,具體代碼如下:
public void useGsonParser3(){
String json3="[{\"name\" : \"jack\", \"age\" : 10},{\"name\" : \"rose\", \"age\" : 11}]";
Gson gson=new Gson();
List<Person1> person2=gson.fromJson(json3,new TypeToken<ArrayList<Person1>>(){}.getType());
for(int i=0;i<person2.size();i++){
//根據(jù)i的位置獲取JSONObject
Person1 person1 = person2.get(i);
String name = person1.getName();
int age=person1.getAge();
Log.i("UseGsonActivity","name"+i+":"+name);
Log.i("UseGsonActivity","age"+i+":"+age);
}
}
想要的數(shù)據(jù)依然全部都獲取到了。
上面的Gson介紹,基本上可以滿足絕大多數(shù)的開發(fā)需求。
三 、插件GsonFormat快速實現(xiàn)JavaBean
上面我們介紹了,使用Gson開源庫解析JSON數(shù)據(jù),大家可能會發(fā)現(xiàn)雖然解析代碼比較簡單,但是還需要自己按照規(guī)則寫一個javaBean。
好消息來了,通過AndroidStudio插件,你甚至不需要再手動寫JavaBean了,讓你立刻完成~

GsonFormat 插件安裝
重啟完了,接下來就是見證奇跡的時刻了。
我們以下面的JSON為例,讓大家看看如何快速生成JavaBean:
{
"showapi_res_code": 0,
"showapi_res_error": "",
"showapi_res_body": {
"areaCode": "0871",
"city": "昆明",
"name": "中國電信",
"num": 1890871,
"postCode": "650000",
"prov": "云南",
"provCode": "530000",
"ret_code": 0,
"type": 2
}
}

使用方式,在實體類中使用Generate的快捷鍵。默認快捷鍵 alt+Insert。


好,Gson的解析和GsonFormat自動生成實體類就介紹到這里了,是不是有種 "柳暗花明又一村"的感覺。