你的位置:首页 > 操作系统

[操作系统]【轻松一刻】实战项目开发(一) 解析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 类。

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

 

先看一张效果图吧。

   

 

未完待续。。。。