一些简单的JSON格式解析可以直接使用JSONObject和JSONArray来解析,但是面对比较复杂或者是数据量较大的JSON数据时就需要使用fastJSON和Gson来解析了,这样的效率和效果都更好。

这里介绍本次项目使用到的Gson解析,fastJSON类似,但是由于如果包含了fastJSON,那么在proguard混淆的时候需要在rule中包含以下内容:

1
2
-keepattributes Signature     // 避免混淆泛型
-keepattributes *Annotation* // 不混淆注解

如果不包含的话,就会出现以下几个问题:
1. 加了符号Annotation的实体属性后,一使用就崩溃
2. 当有泛型属性时,一使用就崩溃

接下来就先总结一下Gson的解析

GSON 简单解析

先是解析JSONObject

1
2
Gson gson = new Gson();
Person person = gson.fromJson(response, Person.class);

再是解析JSONArray
需要借助TypeToken将期望解析成的数据类型传入fromJson方法

1
2
Gson gson = new Gson();
List<Person> datas = gson.fromJson(response, new TypeToken<List<Person>>(){}.getType());

GSON 复杂解析

JSON返回的数据如下:

1
{"code":0,"desc":"Success","content":{"grade":14,"signin":false,"room":"","docs":[{"id":331,"docname":"[SFTM财务系统改善]成本支付-2.xlsxsdfsdfsdfsdfsdfsdfsdfsdfsdfsdfsd.xlsx","pagecnt":8,"doctime":"2015-11-28"},{"id":332,"docname":"外勤1.0需求细分列表修改版.docx","pagecnt":4,"doctime":"2015-11-28"},{"id":333,"docname":"1.docx","pagecnt":1,"doctime":"2015-11-29"},{"id":334,"docname":"要件签字封面(部品单价).xls","pagecnt":3,"doctime":"2015-11-29"}],"printer":[{"id":1,"address":"5104"}]}}

上面的JSON数据总结一下,也就包含以下几个内容:
首先第一层是code, desc,content
第二层content中包含以下的内容:grade, signin, room, docs,printer
第三层docs中包含以下内容: id, docname, pagecnt, doctime
第三层printer中包含以下内容:id, address

对于这种比较复杂的JSON数据格式的解析,可以分成以下几步来做:

  • 创建一个实体
  • 在实体中包含3个属性
  • 创建一个静态内部类,该类中包含的属性就是content中存在的内容,也就是grade, signin, room, docs,printer。如果content是一个[],就应该定义为List,如果是{},就定义为DocContent
  • 再在content创建的静态内部类中创建两个静态内部类:Docs和Printer

总体的效果如下:
第一层

1
2
3
private int code;
private String desc;
private DocContent content;

第二层

1
2
3
4
5
6
7
public static class DocContent {
private int grade;
private Boolean signin;
private String room;
private List<Docs> docs;
private List<Printer> printer;
}

第三层

1
2
3
4
5
6
7
8
9
10
public static class Docs {
private String docname;
private int pagecnt;
private String doctime;
}

public static class Printer {
private int id;
private String address;
}

当然咯,其中还要包括各种setter和getter方法,只需要注意一点,这里的属性被声明为List是因为这个是一个JSONArray,对于JSONObject只需要直接定义

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
public class JsonDatas_DocInfo {

public int getCode() {
return code;
}

public void setCode(int code) {
this.code = code;
}

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

public DocContent getContent() {
return content;
}

public void setContent(DocContent content) {
this.content = content;
}

private int code;
private String desc;
private DocContent content;

public static class DocContent {
public int getGrade() {
return grade;
}

public void setGrade(int grade) {
this.grade = grade;
}

public Boolean getSignin() {
return signin;
}

public void setSignin(Boolean signin) {
this.signin = signin;
}

public String getRoom() {
return room;
}

public void setRoom(String room) {
this.room = room;
}

public List<Docs> getDocs() {
return docs;
}

public void setDocs(List<Docs> docs) {
this.docs = docs;
}

public List<Printer> getPrinter() {
return printer;
}

public void setPrinter(List<Printer> printer) {
this.printer = printer;
}

private int grade;
private Boolean signin;
private String room;
private List<Docs> docs;
private List<Printer> printer;

public static class Docs {
private int id;

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getDocname() {
return docname;
}

public void setDocname(String docname) {
this.docname = docname;
}

public int getPagecnt() {
return pagecnt;
}

public void setPagecnt(int pagecnt) {
this.pagecnt = pagecnt;
}

public String getDoctime() {
return doctime;
}

public void setDoctime(String doctime) {
this.doctime = doctime;
}

private String docname;
private int pagecnt;
private String doctime;
}

public static class Printer {
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

private int id;
private String address;
}
}
}

调用的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Gson gson = new Gson();
JsonDatas_DocInfo jsonDatas_docInfo = gson.fromJson(response, JsonDatas_DocInfo.class);
List<JsonDatas_DocInfo.DocContent.Docs> docs = jsonDatas_docInfo.getContent().getDocs();

if (docs != null) {
for (JsonDatas_DocInfo.DocContent.Docs tempDoc : docs) {
final int id = tempDoc.getId();
final String docname = tempDoc.getDocname();
final int pagecnt = tempDoc.getPagecnt();
final String doctime = tempDoc.getDoctime();

Log.d("info", id + ", docname:" + docname + ", pagecnt : " +
pagecnt + ", doctime : " + doctime);
listDocInfo.add(new DocInfo(id, docname, pagecnt, doctime));
}

handler.sendMessage(msg);
}