好東西,大家享
原文來自: http://www.iamxiarui.com/2016/08/30/android
原文作者:iamxiarui
1、簡單的JSON資料進行解析
[
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
這個是最簡單的一種Json數組格式,Gson可以直接将其解析成一個List。
首先,我們需要建立一個Bean對象,注意變量名要與字段名稱名稱保持一緻。
推薦使用Android Studio 的GsonFormat工具
public class UserBean {
//變量名跟JSON資料的字段名需要一緻
private String name ;
private String age;
private String phone;
private String email;
...
}
之後為解析過程:
/**
* 解析沒有資料頭的純數組
*/
private void parseNoHeaderJArray() {
//拿到本地JSON 并轉成String
String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_1);
//Json的解析類對象
JsonParser parser = new JsonParser();
//将JSON的String 轉成一個JsonArray對象
JsonArray jsonArray = parser.parse(strByJson).getAsJsonArray();
Gson gson = new Gson();
ArrayList<UserBean> userBeanList = new ArrayList<>();
//加強for循環周遊JsonArray
for (JsonElement user : jsonArray) {
//使用GSON,直接轉成Bean對象
UserBean userBean = gson.fromJson(user, UserBean.class);
userBeanList.add(userBean);
}
mainLView.setAdapter(new UserAdapter(this, userBeanList));
}
可以總結出解析步驟為:
①、将網絡請求過來的JSON資料轉換成String類型資料;
②、當JSON内隻有純屬組,用JSON解析類對象将JSON字元串轉為JsonArray;
③、周遊Json數組,使用Gson進行解析。
a、JsonParse:解析類,它可以将Json資料分别通過getAsJsonObject 和 getAsJsonArray 解析成 JsonObject 和JsonArray 。
b、JsonElement:一個抽象類,代表Json字元串内某個元素例如:JsonObject/JsonArray/JsonPrimitive/...
2、有資料頭的純數組資料
Json字元串如下,僅僅在最最簡單的基礎上加了一個約定好的名稱為:"muser" 的資料頭
{
"muser": [
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
使用上面提到的 JsonParse 進行相關操作
/**
* 解析有資料頭的純數組
*/
private void parseHaveHeaderJArray() {
//拿到本地JSON 并轉成String
String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_2);
//先轉JsonObject
JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
//再轉JsonArray 加上資料頭
JsonArray jsonArray = jsonObject.getAsJsonArray("muser");
Gson gson = new Gson();
ArrayList<UserBean> userBeanList = new ArrayList<>();
//循環周遊
for (JsonElement user : jsonArray) {
//通過反射 得到UserBean.class
UserBean userBean = gson.fromJson(user, new TypeToken<UserBean>() {}.getType());
userBeanList.add(userBean);
}
mainLView.setAdapter(new UserAdapter(this, userBeanList));
}
c、TypeToken:為匿名反射類
以下為官方說明:
GSON 提供了 TypeToken 這個類來幫助我們捕獲(capture)像 List 這樣的泛型資訊。Java編譯器會把捕獲到的泛型資訊編譯到這個匿名内部類裡,然後在運作時就可以被 getType() 方法用反射的 API 提取到。
官方要表達的話是:
将泛型 T 轉成 .class 。比如上面的 TypeToken 經過 getType() 後就是UserBean.class 。
對于上面的 JSON 完全可以直接通過 GSON 轉成 List ,不用這麼麻煩,我隻是為了引出3個小知識。
3、有資料頭的複雜資料
Json的字元串如下:
{
"code": 200,
"msg": "OK",
"muser": [
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
仔細觀察這個字元串結構發現上面多了兩個字段
"code": 200
"msg": "OK"
首先建立Bean類,這裡再次強調使用Android Studio 的GsonFormat工具
此處省略set/get方法
/**
* Created by xiarui on 2016/8/30.
* 傳回所有結果的Bean
*/
public class ResultBean {
//注意變量名與字段名一緻
private int code;
private String msg;
private List<UserBean> muser;
public class UserBean{
private String name ;
private String age;
private String phone;
private String email;
...
}
...
}
注意:
這個 ResultBean 裡面有一個 UserBean 。 它雖然跟上面第一第二招雖然内容一樣,但是作用不一樣,這是作為 JsonArray 解析後存入List 中的對象。
解析代碼如下:
/**
* 有消息頭 複雜資料 正常方式
*/
private void parseComplexJArrayByCommon() {
//拿到Json字元串
String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
//GSON直接解析成對象
ResultBean resultBean = new Gson().fromJson(strByJson,ResultBean.class);
//對象中拿到集合
List<ResultBean.UserBean> userBeanList = resultBean.getMuser();
//展示到UI中
mainLView.setAdapter(new ResultAdapter(this, userBeanList));
}
4、隻解析複雜JSON中的數組或數組中的某部分内容
Json字元串和上面的一樣:
{
"code": 200,
"msg": "OK",
"muser": [
{
"name": "zhangsan",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
{
"name": "lisi",
"age": "20",
"phone": "22222",
"email": "[email protected]"
},
...
]
}
對于這個問題,不需要一一進行解析,但是有一點需要做的是,需要周遊。
完整代碼解析代碼如下:
/**
* 有資料頭 複雜資料 截取方式
*/
private void parseComplexJArrayByDirect() {
//拿到JSON字元串
String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_3);
List<UserBean> userBeanList = new ArrayList<>();
//拿到數組
JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
JsonArray jsonArray = jsonObject.getAsJsonArray("muser");
//循環周遊數組
for (JsonElement user : jsonArray) {
UserBean userBean = new Gson().fromJson(user, new TypeToken<UserBean>() {
}.getType());
//根據條件過濾
if (Integer.parseInt(userBean.getAge()) > 30) {
userBeanList.add(userBean);
}
}
mainLView.setAdapter(new UserAdapter(this, userBeanList));
}
5、若Json資料非常非常複雜如下
{
"group": {
"user": {
"name": "張三",
"age": "10",
"phone": "11111",
"email": "[email protected]"
},
"info": {
"address": "北京",
"work": "Android Dev",
"pay": "10K",
"motto": "先定一個小目标,比如我先賺一個億"
}
}
}
具體解析方式如下(不要問我為啥?我看來的!!!):
/**
* 通過JsonReader的方式去解析
*/
private void parseComplexJArrayByReader() throws IOException {
String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_4);
JsonReader reader = new JsonReader(new StringReader(strByJson));
try {
reader.beginObject();
String tagName = reader.nextName();
if (tagName.equals("group")) {
//讀group這個節點
readGroup(reader);
}
reader.endObject();
} finally {
reader.close();
}
}
/**
* 讀group這個節點
*
* @param reader JsonReader
*/
private void readGroup(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
String tagName = reader.nextName();
if (tagName.equals("user")) {
readUser(reader);
} else if (tagName.equals("info")) {
readInfo(reader);
}
}
reader.endObject();
}
/**
* 讀使用者基本消息 user節點
*
* @param reader JsonReader
*/
private void readUser(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
String tag = reader.nextName();
if (tag.equals("name")) {
String name = reader.nextString();
nameText.setText(name);
} else if (tag.equals("age")) {
String age = reader.nextString();
ageText.setText(age);
}
...
else {
reader.skipValue();//忽略
}
}
reader.endObject();
}
/**
* 讀使用者其他消息 info節點
*
* @param reader JsonReader
*/
private void readInfo(JsonReader reader) throws IOException {
reader.beginObject();
while (reader.hasNext()) {
String tag = reader.nextName();
if (tag.equals("address")) {
String address = reader.nextString();
addressText.setText(address);
} else if (tag.equals("work")) {
String work = reader.nextString();
workText.setText(work);
}
...
else {
reader.skipValue();//忽略
}
}
reader.endObject();
}