【轻便一刻】实战项目开发(一) 解析JSON数据 得到adapter的数据源

【轻松一刻】实战项目开发(一) 解析JSON数据 得到adapter的数据源

并不会详细写三方控件如何引入项目,不会贴完整的代码。应用完成后会开源,虽然从目前看没什么大的价值。

只记录写代码过程中遇到的问题,以及如何解决。

 

市面上同质的应用多如牛毛,所以写这个也是为了练手。废话不多说。

 

应用的主题是笑话和趣图,既然要展示笑话内容,就要有个数据源。基本上有三种方法拿到数据源,1.从本地读取,

2.从网络上爬取,3.从三方sdk接口获取。第一种方式与我开发的初衷背道而驰,不想做单机的,第二种方式,目前

水平还不够,且爬取数据不能保证数据源的稳定性,综上从三方接口获取最方便稳定。

 

选择聚合数据sdk 笑话大全接口。

 

官网上有示例,发送请求得到的json数据格式如下:

【轻便一刻】实战项目开发(一)  解析JSON数据 得到adapter的数据源

 

下面我们可以使用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 类。

容易混淆,后期会考虑更换成别的类名。

 

先看一张效果图吧。

【轻便一刻】实战项目开发(一)  解析JSON数据 得到adapter的数据源   【轻便一刻】实战项目开发(一)  解析JSON数据 得到adapter的数据源

 

未完待续。。。。

1楼路上的脚印
写得简洁明了,期待后续的讲解
Re: sphere
@路上的脚印,谢谢支持!