【轻便一刻】实战项目开发(一) 解析JSON数据 得到adapter的数据源
并不会详细写三方控件如何引入项目,不会贴完整的代码。应用完成后会开源,虽然从目前看没什么大的价值。
只记录写代码过程中遇到的问题,以及如何解决。
市面上同质的应用多如牛毛,所以写这个也是为了练手。废话不多说。
应用的主题是笑话和趣图,既然要展示笑话内容,就要有个数据源。基本上有三种方法拿到数据源,1.从本地读取,
2.从网络上爬取,3.从三方sdk接口获取。第一种方式与我开发的初衷背道而驰,不想做单机的,第二种方式,目前
水平还不够,且爬取数据不能保证数据源的稳定性,综上从三方接口获取最方便稳定。
选择聚合数据sdk 笑话大全接口。
官网上有示例,发送请求得到的json数据格式如下:
下面我们可以使用http://www.bejson.com/json2javapojo/ 提供的转换工具生成Json数据对应POJO类以便解析、
当然也可以自己动手写
可以看到json字符串中包含的data是一个Json的数组,最小的单元就是一条笑话数据了,例如
{ "content":"大学时期比较穷,为了赚点上网玩游戏的钱,老王宿舍的几个哥们想出了办法:“老大帮人写作业,老二帮人写作文,老三帮人写情书,老王帮人写检讨。” 后来他们4个成了学校有名的文房四宝。", "hashId":"ACD50D5A66C2201566CF53138901A716", "unixtime":1441868049, "updatetime":"2015-09-10 14:54:09" }
我们先将他抽象出来,如下:
public class Data { private String content; private String hashId; private Long unixtime; private String updatetime; public Data() { } public Data(String content, String hashId, Long unixtime,String updatetime) { super(); this.content = content; this.unixtime = unixtime; this.hashId = hashId; this.updatetime = updatetime; } public String getContent() { return content; } public String getUpdatetime() { return updatetime; } public String getHashId() { return hashId; } public Long getUnixtime() { return unixtime; } @Override public String toString() { return "Data [content=" + content + ", unixtime=" + unixtime + ", hashId=" + hashId + ", updatetime=" + updatetime + "]"; } /** * 因为更新时间和unixtime都不是唯一的 * 这里使用唯一标识hashId来得到哈希码 */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((hashId == null) ? 0 : hashId.hashCode()); return result; } /** * 因为更新时间和unixtime都不是唯一的 * 这里使用唯一标识hashId来比较 */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Data other = (Data) obj; if (hashId == null) { if (other.hashId != null) return false; } else if (!hashId.equals(other.hashId)) return false; return true; }
整个Json数据的POJO类如下:
package com.sphere.joke.entity; import java.util.List; /** * 对应给定的json字符串 创建POJO实体类 */ public class Message { private int error_code; private String reason; private List<Data> result; public Message(int error_code, String reason, List<Data> result) { this.error_code = error_code; this.reason = reason; this.result = result; } public int getError_code() { return this.error_code; } public String getReason() { return this.reason; } public List<Data> getResult() { return result; } @Override public String toString() { return "Message [error_code=" + error_code + ", reason=" + reason + ", result=" + result + "]"; } }
我们的目的就是得到result作为显示列表adapter的数据源。
好了,POJO实体我们已经建好了,那么拿到Json数据后如何解析呢,
下面使使用GSON提供的API解析我们拿到的JSON数据,
将gson-2.2.4.jar引入工程
我们新建一个解析类 ParseJson.java
先从最小的单元开始,从内至外解析。
解析一条笑话数据 并返回Data的示例 如下
/** * 解析json字符中的最小单元 * @param reader * @return * @throws IOException */ public Data readData(JsonReader reader) throws IOException{ String content = null; String hashId = null; Long unixtime = 0L; String updatetime = null; reader.beginObject(); while(reader.hasNext()){ String name = reader.nextName(); if(name.equals("content")){ //替换掉 \t \s \n \r content = UtilsHelper.replaceBlank(reader.nextString()); }else if(name.equals("hashId")){ hashId = reader.nextString(); }else if(name.equals("unixtime")){ unixtime = reader.nextLong(); }else if(name.equals("updatetime")){ updatetime = reader.nextString(); }else { reader.skipValue(); } } reader.endObject(); return new Data(content,hashId, unixtime, updatetime); }
解析data数组 如下
/** * 返回内部json数组的解析结果集 * @param reader * @return * @throws IOException */ public List<Data> readDatasArray(JsonReader reader) throws IOException{ List<Data> datas = new ArrayList<Data>(); reader.beginArray(); while(reader.hasNext()){ datas.add(readData(reader)); } reader.endArray(); return datas; }
得到message对象
/** * 使用JsonReader解析json字符 * @param reader * @return * @throws IOException */ public Message readMessage(JsonReader reader) throws IOException { int error_code = 0; String reason = null; List<Data> result = null; // 开始解析对象 reader.beginObject(); while(reader.hasNext()){ //得到键名 String name = reader.nextName(); if(name.equals("error_code")){ error_code = reader.nextInt(); }else if (name.equals("reason")) { reason = reader.nextString(); }else if(name.equals("result")){ // result对应的是json数组集-> data reader.beginObject(); while(reader.hasNext()){ String tagName = reader.nextName(); if(tagName.equals("data")){ result = readDatasArray(reader); }else{ reader.skipValue(); } } reader.endObject(); }else { reader.skipValue(); } } // 结束解析 reader.endObject(); return new Message(error_code, reason, result); }
好的。我们测试下
Message msg = mParser.readMessage(new JsonReader(new StringReader(jsonResult))); System.out.println(msg.getResult()); List<Data> list = msg.getResult(); for (Data data : list) { System.out.println(data); }
得到result的结果:
Data [content=记得小时候有一回老师让写作文,要求很简单,只要是能让她看哭就算通过。 第二天,我一哥们把作文交给老师,老师翻开后,边打喷嚏边哭。 一老师看见后问:“这作文真的很感人吗?” 老师边哭边说:“哪个王八蛋往上面撒的胡椒粉!”, unixtime=1441871137, updatetime=2015-09-10 15:45:37] Data [content=开着小队语音玩英雄联盟,开局十分钟打出了优势。 突然我们ADC就不动弹了,耳机里隐约传来一声咆哮:“你不做饭在这玩游戏,把孩子饿成什么样了?这日子还过不过了。” 然后ADC掉线了。, unixtime=1441870406, updatetime=2015-09-10 15:33:26] Data [content=今天跟人干了一架,今天在街上站着等朋友,来了个乞丐,比手画脚的跟我讨钱。 我一看准是个骗子,就也比手画脚的给他打发了。 临走了他来了句:“靠,碰见哑巴了!” 我一听火大了:“你他妈才哑巴呢!” 最后干起来了,现在手都肿了。, unixtime=1441870406, updatetime=2015-09-10 15:33:26] Data [content=有一位记者采访精神病院院长,怎样确定病人已经治愈,可以出院。 院长说:“很简单,把浴缸注满水,旁边放一把汤匙一把舀勺,要求把浴缸腾空。” 记者说:“噢!正常的会使用舀勺。” 院长说:“不,正常的会把浴缸的塞子拔掉。”, unixtime=1441870406, updatetime=2015-09-10 15:33:26] Data [content=昨天晚上,朋友喊我去k歌,让我开车去,来到ktv门口,我下车把钥匙递给服务员,说,帮我把车停一下,顺便给了他100块小费,只见他看着我,把100块还给我,又从钱包里拿出100块,说,大哥,这车你自己停吧!拖拉机,我真的开不好,我……, unixtime=1441870383, updatetime=2015-09-10 15:33:03] Data [content=朋友送了一份非常名贵的咖啡,刚刚煮了一杯,我就趁机教育弟弟:“人生就像这杯咖啡,你闻着香,可我喝着苦。” 弟弟说:“哥,要不你就闻闻香,咖啡我来喝。”, unixtime=1441869206, updatetime=2015-09-10 15:13:26] Data [content=老婆:“亲爱的,今天把房间好好整理一下!” 老公:“如何整理呀?” 老婆:“把你的臭鞋子臭袜子烟灰等凡是与你有关的统统给我丢掉。” 老公:“遵命!老婆,搓衣板也丢掉吗?” 老婆:“丫的,搓衣板是你的吗?” 老公:“是我天天要跪的肯定是我的呀。” 老婆:“你只有使用权,所有权归我,你敢仍了,仍到那你就以后跪到那!”, unixtime=1441868754, updatetime=2015-09-10 15:05:54] Data [content=一少妇给儿子喂奶,小孩儿饿极好一顿狂吮猛吸,少妇见状十分动情:这孩子,比我们单位领导还厉害!好兆头啊,长大了肯定是个当一把手的!, unixtime=1441868586, updatetime=2015-09-10 15:03:06] Data [content=有一女子问到:“老公你喜不喜欢每天这样,下了班和我花前月下的?” 她老公说:“月下可以,花钱不行!”, unixtime=1441868049, updatetime=2015-09-10 14:54:09] Data [content=大学时期比较穷,为了赚点上网玩游戏的钱,老王宿舍的几个哥们想出了办法:“老大帮人写作业,老二帮人写作文,老三帮人写情书,老王帮人写检讨。” 后来他们4个成了学校有名的文房四宝。, unixtime=1441868049, updatetime=2015-09-10 14:54:09]
好了,数据源已经解析成功了,接下来就是在listview中展示了。
这里有个不好的地方,我们自己写了个Message类,但是android也提供android.os.Message 类。
容易混淆,后期会考虑更换成别的类名。
先看一张效果图吧。
未完待续。。。。
- 1楼路上的脚印
- 写得简洁明了,期待后续的讲解
- Re: sphere
- @路上的脚印,谢谢支持!