【輕鬆一刻】實戰項目開發(一) 解析JSON資料 得到adapter的資料來源,jsonadapter
並不會詳細寫三方控制項如何引入項目,不會貼完整的代碼。應用完成後會開源,雖然從目前看沒什麼大的價值。
只記錄寫代碼過程中遇到的問題,以及如何解決。
市面上同質的應用多如牛毛,所以寫這個也是為了練手。廢話不多說。
應用的主題是笑話和趣圖,既然要展示笑話內容,就要有個資料來源。基本上有三種方法拿到資料來源,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 類。
容易混淆,後期會考慮更換成別的類名。
先看一張吧。
未完待續。。。。