androidgson解析json
⑴ Android Gson 使用詳解
Json 是一種文本形式的數據交換格式,比 xml 更為輕量。Json 的解析和生成的方式很多,在 Android 平台上最常用的類庫有 Gson 和 FastJson 兩種,這里要介紹的是 Gson
Gson 的 GitHub 主頁點擊這里: Gson
在進行序列化與反序列操作前,需要先實例化一個 com .google.gson.Gson 對象,獲取 Gson 對象的方法有兩種
利用 Gson 可以很方便地生成 Json 字元串,通過使用 addProperty 的四個重載方法
addProperty 方法底層調用的是 add(String property, JsonElement value) 方法,即將基本數據類型轉化為了 JsonElement 對象,JsonElement 是一個抽象類,而 JsonObject 繼承了 JsonElement ,因此我們可以通過 JsonObject 自己來構建一個 JsonElement
Json數組 與 字元串數組
Json數組 與 List
Gson 也提供了 toJson() 和 fromJson() 兩個方法用於轉化 Model 與 Json,前者實現了序列化,後者實現了反序列化
首先,聲明一個 User 類
序列化的方法很簡單,調用 gson 對象的 toJson 方法,傳入要序列化的對象
反序化的方式也類似
繼續使用上一節聲明的 User 類,根據 User 類聲明的各個屬性名,移動端的開發者希望介面返回的數據格式即是如下這樣的
如果沒有和伺服器端溝通好或者是 API 改版了,介面返回的數據格式可能是這樣的
如果繼續使用上一節介紹的方法,那無疑會解析出錯
例如
name 屬性值解析不到,所以為 null
此時為了兼顧多種格式的數據,就需要使用 SerializedName 註解
根據 SerializedName 的聲明來看,SerializedName 包含兩個屬性值,一個是字元串,一個是字元串數組,而字元串數組含有默認值
SerializedName 的作用是為了在序列化或反序列化時,指導 Gson 如果將原有的屬性名和其它特殊情況下的屬性名聯系起來
例如,修改 User 類,為 name 聲明 SerializedName 註解,註解值為 userName
在序列時,Json 格式就會相應改變
在反序列化時也一樣,能夠解析到正確的屬性值
還有個問題沒解決,為了應對多種屬性名不一致的情況,難道我們要聲明多個 User 類嗎?這顯然是不現實的,所以還需要為 User 類設置多個備選屬性名,這就需要用到 SerializedName 註解的另一個屬性值 alternate 了。
以下幾種情況都能夠被正確的反序列化
有時候並不是所有的欄位都需要進行系列化和反序列化,因此需要對某些欄位進行排除,有四種方法可以來實現這種需求。
Expose 註解包含兩個屬性值,且均聲明了默認值。Expose 的含義即為「暴露」,即用於對外暴露欄位,serialize 用於指定是否進行序列化,deserialize 用於指定是否進行反序列化。如果欄位不聲明 Expose 註解,則意味著不進行序列化和反序列化操作,相當於兩個屬性值均為 false 。此外,Expose 註解需要和 GsonBuilder 構建的 Gson 對象一起使用才能生效。
Expose 註解的註解值聲明情況有四種
現在來看個例子,修改 User 類
按照如上的註解值,只有聲明了 Expose 註解且 serialize 值為 true 的欄位才能被序列化,只有聲明了 Expose 註解且 deserialize 值為 true 的欄位才能被反序列化
Gson 提供了 @Since 和 @Until 兩個註解基於版本對欄位進行過濾,@Since 和 @Until 都包含一個 Double 屬性值,用於設置版本號。Since 的意思是「自……開始」,Until 的意思是「到……為止」,一樣要和 GsonBuilder 配合使用。
當版本( GsonBuilder 設置的版本) 大於或等於 Since 屬性值或小於 Until 屬性值時欄位會進行序列化和反序列化操作,而沒有聲明註解的欄位都會加入序列化和反序列操作
現在來看個例子,修改 User 類
訪問修飾符由 java.lang.reflect.Modifier 提供 int 類型的定義,而 GsonBuilder 對象的 excludeFieldsWithModifiers 方法接收一個 int 類型可變參數,指定不進行序列化和反序列化操作的訪問修飾符欄位
看個例子
GsonBuilder 類包含 setExclusionStrategies(ExclusionStrategy... strategies) 方法用於傳入不定長參數的策略方法,用於直接排除指定欄位名或者指定欄位類型
看個例子
欄位名為 "intField" 和欄位類型為 double 的欄位都會被排除掉
setExclusionStrategies 方法在序列化和反序列化時都會生效,如果只是想指定其中一種情況下的排除策略或分別指定排除策略,可以改為使用以下兩個方法
對於 Gson 而言,在序列化時如果某個屬性值為 null 的話,那麼在序列化時該欄位不會參與進來,如果想要顯示輸出該欄位的話,可以通過 GsonBuilder 進行配置
默認的序列化後的 Josn 字元串並不太直觀,可以選擇格式化輸出
Gson 也可以對時間值進行格式化
TypeAdapter 是一個泛型抽象類,用於接管某種類型的序列化和反序列化過程,包含兩個抽象方法,分別用於自定義序列化和反序列化過程
下面看個簡單的例子
定義 TypeAdapter 的子類 UserTypeAdapter 來接管 User 類的序列化和反序列化過程
這里設定當 User 類序列化時 Json 中的Key值都是大寫字母開頭,反序列化時支持「name」和「Name」兩種不同的 Json 風格
可以看到 User 類按照預定義的策略來完成序列化和反序列化了
TypeAdapter 將序列化和反序列操作都接管了過來,其實 Gson 還提供了只接管序列化過程的介面,即 JsonSerializer
看個例子
相對應的,JsonDeserializer 介面提供了反序列化的介面
這里有個比較麻煩的地方,那就是在使用 TypeAdapter 、JsonSerializer 和 JsonDeserializer 時,總需要調用 registerTypeAdapter 方法進行注冊,那有沒有更簡單的注冊方法呢?
有的,Gosn 還提供了另一個註解 @JsonAdapter 用於進行簡單的聲明
類似於這樣,聲明了 User 類的序列化或反序列化操作由 UserTypeAdapter 完成,註解的優先順序高於 registerTypeAdapter 方法
TypeAdapterFactory 是用於創建 TypeAdapter 的工廠類,通過參數 TypeToken 來查找確定對應的 TypeAdapter,如果沒有就返回 null 並由 Gson 默認的處理方法來進行序列化和反序列化操作,否則就由用戶預定義的 TypeAdapter 來進行處理
這一篇文章好像寫得太長了一點?Gson 的知識點介紹到這里也差不多了,以後如果還發現新內容的話我會繼續補充,現在就先這樣啦
⑵ android中json解析後的數據怎樣顯示在手機上
android中json解析有很多種方式,解析完,直接給TextView賦值即可
以下為android中常見的JSON解析類庫
1. android SDK:androidSDK中自帶的JSONObject
2. gson google專門為androd開發的json解析框架
3.jackson java EE Spring中的json轉換工具
4.json-lib: JSON-lib框架,轉換JSON、XML
在Java EE中使用最廣泛的是Jackson Json,使用非常方便而且效率極高;另外還有兩個比較有名氣的是Gson和JSON-lib,某些大俠已經對它們做了對比實驗,結論如下執行效率:Jackson>Gson>JSON-lib
⑶ android使用gson解析嵌套復雜的json數據,數據怎麼顯示到布局上,布局怎麼寫
首先先講一個比較簡單點的例子(最簡單的我就不講啦,網上很多),幫助新手理解Gson的使用方法:
比如我們要解析一個下面這種的Json:
String json = {"a":"100","b":[{"b1":"b_value1","b2":"b_value2"},{"b1":"b_value1","b2":"b_value2"}],"c":{"c1":"c_value1","c2":"c_value2"}}
首先我們需要定義一個序列化的Bean,這里採用內部類的形式,看起來會比較清晰一些:
public class JsonBean {
public String a;
public List<B> b;
public C c;
public static class B {
public String b1;
public String b2;
}
public static class C {
public String c1;
public String c2;
}
}
很多時候大家都是不知道這個Bean是該怎麼定義,這裡面需要注意幾點:
1、內部嵌套的類必須是static的,要不然解析會出錯;
2、類裡面的屬性名必須跟Json欄位裡面的Key是一模一樣的;
3、內部嵌套的用[]括起來的部分是一個List,所以定義為 public List<B> b,而只用{}嵌套的就定義為 public C c,
具體的大家對照Json字元串看看就明白了,不明白的我們可以互相交流,本人也是開發新手!
Gson gson = new Gson();
java.lang.reflect.Type type = new TypeToken<JsonBean>() {}.getType();
JsonBean jsonBean = gson.fromJson(json, type);
然後想拿數據就很簡單啦,直接在jsonBean裡面取就可以了!
如果需要解析的Json嵌套了很多層,同樣可以可以定義一個嵌套很多層內部類的Bean,需要細心的對照Json欄位來定義哦。
⑷ android開發用gson解析json字元串,如果鍵不是固定值怎麼辦
這樣沒試過,不過我認為可以將json中鍵值不固定的存在JSONArray中訪問時奇數位保存鍵,偶數保存值;也可以只傳值;還有就是多層嵌套(例如:假設字母表示鍵,數字表示值:a:2,b:5替換成i:a,ii:2,iii:b,iiii:5這意思就是將鍵與值都作為值傳過來)。要麼每一次變化都寫一個類來與之對應,不同的時候用不同的類的實例接收
⑸ Android studio使用Retrofit框架,Get發送請求,Gson解析返回的json數據時報錯怎麼辦
資料庫一直以來給我的感覺就是——麻煩!!!
接觸了Realm之後才終於可以開開心心的使用資料庫了。
本文總結一些Realm資料庫的常用知識點,包括多線程訪問,以及如何與Retrofit2.0一起使用等...
看懂這些知識點之後,個人認為就可以在一般的項目中使用Realm了。
1. model類必須extends RealmObject,所有屬性必須用private修飾
2. model中支持基本數據結構:boolean, byte, short, ìnt, long, float, double, String, Dateand byte[]
3.若要使用List必須用RealmList<T>,或者繼承RealmList
4.與Retrofit2.*一起使用,通過Gson來解析Json數據並直接生成RealmObject,可參考如下寫法:
[java] view plain
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
⑹ android gson可以只解析json中想要的屬性嗎
當然可以,按照格式只解析你需要的;其它可以不管。
⑺ android中gson怎麼解析json數組
首先要導入Gson包;
例如有個penson類:
Gson gson = new Gson();
String json ;
person[] pers = gson. fromJson (json , person[].class);
⑻ Android 如何引用本地json文件
有時候遇到要一些模擬數據的時候,要麼寫個List<T>,要麼寫死.
然後數據比較多的時候可以引用本地資源文件,記錄下如何使用本地json文件
<1>在java同級目錄下創建"assets"資源文件夾
<2>編輯json文本內容
至於json文件夾內容 就自定義了,想要什麼內容寫什麼,對於一個做項目多了的開發者而言 json數據是熟悉到不能再熟悉的了
以下是我在淘寶一個個復制過來自己拼裝的一些商品數據
不需要加任何標識,只需要標準的json數據格式就可以了
<3>引用和json解析的工具類,解析用的 Gson也是經常用到的
<4>最後在需要的地方引用,"ExchangeBean"是根據json內容寫的一個模型,用於接收存放數據
有時間再補上demo,下面是效果圖:
⑼ gson怎麼解析jsonarray
Json是一種類似於XML的通用數據交換格式,具有比XML更高的傳輸效率.
從結構上看,所有的數據(data)最終都可以分解成三種類型:
第一種類型是標量(scalar),也就是一個單獨的字元串(string)或數字(numbers),比如"北京"這個單獨的詞。
第二種類型是序列(sequence),也就是若干個相關的數據按照一定順序並列在一起,又叫做數組(array)或列表(List),比如"北京,上海"。
第三種類型是映射(mapping),也就是一個名/值對(Name/value),即數據有一個名稱,還有一個與之相對應的值,這又稱作散列(hash)或字典(dictionary),比如"首都:北京"。
Json的規格非常簡單,只用一個頁面幾百個字就能說清楚,而且Douglas Crockford聲稱這個規格永遠不必升級,因為該規定的都規定了。
1) 並列的數據之間用逗號(",")分隔。
2) 映射用冒號(":")表示。
3) 並列數據的集合(數組)用方括弧("[]")表示。
4) 映射的集合(對象)用大括弧("{}")表示。
在Android中可以使用Gson解析JSON數據
首先,從 code.google.com/p/google-gson/downloads/list下載GsonAPI:
google-gson-1.7.1-release.zip
把gson-1.7.jar 到libs(項目根目錄新建一個libs文件夾)中。
可以使用以下兩種方法解析JSON數據:
通過獲取JsonReader對象解析JSON數據:
⑽ android中gson解析怎樣防止參數確實
最近在做天氣預報的項目,需要用到多重JSON的解析,這里我選用了目前流行的,也公認是最簡單易用的框架GSON來解析這個復雜的JSON,雖然在最後結果很簡單,但並不意味著整個過程很簡單,沒有一點問題,恰恰是相反的,我是第一次學習這個GSON,雖然在網上看博客一看即知怎麼操作,但是一動手,卻發生問題還是有的。
首先,先上我的JSON結構:
{"desc":"OK","status":1000,"data":{"wen":"15","ganmao":"晝夜溫差很大,易發生感冒,請注意適當增減衣服,加強自我防護避免感冒。","forecast":[{"fengxiang":"南風","fengli":"微風級","high":"高溫16℃","type":"晴","low":"低溫2℃","date":"14日星期二"},{"fengxiang":"南風","fengli":"微風級","high":"高溫16℃","type":"多雲","low":"低溫4℃","date":"15日星期三"},{"fengxiang":"南風","fengli":"微風級","high":"高溫17℃","type":"多雲","low":"低溫7℃","date":"16日星期四"},{"fengxiang":"南風","fengli":"微風級","high":"高溫16℃","type":"陰","low":"低溫5℃","date":"17日星期五"},{"fengxiang":"南風","fengli":"微風級","high":"高溫19℃","type":"晴","low":"低溫5℃","date":"18日星期六"}],"yesterday":{"fl":"微風","fx":"南風","high":"高溫14℃","type":"晴","low":"低溫2℃","date":"13日星期一"},"aqi":"38","city":"北京"}}
在實現時,我是有進行過分層的,這里,我就忽略了……
首先,照著網上一個簡單的教程,我把JAVABEAN,設置成這樣:
{CSDN:CODE:public class TestBean {
public String desc;
public int status;
public List<Data> data;
public class Data {
public String wen;
public String ganmao;
public List<Forecast> forecast;
public List<Yesterday> yesterday;
public String aqi;
public String city;
public class Forecast {
public String fengxiang;
public String fengli;
public String high;
public String type;
public String low;
public String date;}
public class Yesterday {
public String fl;
public String fx;
public String high;
public String type;
public String low;
public String date;}
}
}}
這里有兩個點想說的,正確的是,一是成員變數名一定是跟JSON的欄位完全一樣的,那個沒有「」的數字數據的話要用int,我一開始照著網上模仿這個,把內層的數據都用一個List<內部類名稱>來表示。結果是失敗的。
接著,我把代碼又拆成了網上分多個類出來,每個類都加多一個getter和setter,我本著大腦想,或許上個想得過於簡單,可能系統還需要重寫toString方法,而且這些都是有規矩的。
如下圖:
做到這里,我還是想驗證所有我不太清楚的點,第一,我改了類名,比如把內部類的名稱改了,這里證明是不會有影響的,但是欄位名是一定要一樣的。第二,我又建了一個和開始一樣的,只有極簡的結構類,嘗試如果沒有 setter和getter有沒有影響,結果是沒影響的,toString也是可有可無的。
總之,只要保證對JSON結果的正確解構,還有分析對象,是單個類,還是一個集合類。
最後,學習的過程中,要盡量地去嘗試,不斷地思考,不要嫌簡單,遇到問題,不要想著去依賴別人幫自己解決,問題千變萬化,自己還得停下來想想。
感謝閱讀,如果不妥的地方,請指出。