一起學Android之Xml與Json解析

来源:https://www.cnblogs.com/hsiang/archive/2019/08/03/11295574.html
-Advertisement-
Play Games

在網路中,數據交互通常是以XML和Json的格式進行,所以對這兩種格式的數據進行解析,是Android開發中的必備功能,本文以一個簡單的小例子,簡述Android開發中Xml和Json解析的常用方式,僅供學習分享使用。 ...


概述

在網路中,數據交互通常是以XML和Json的格式進行,所以對這兩種格式的數據進行解析,是Android開發中的必備功能,本文以一個簡單的小例子,簡述Android開發中Xml和Json解析的常用方式,僅供學習分享使用。

XML解析

Android 提供了三種解析XML的方式:SAX(Simple API XML), DOM(Document Object Model), PULL,本文主要講解Pull的方式解析Xml。

PULL解析Xml優點:PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動設備中使用,Android系統內部在解析各種XML時也是用PULL解析器,Android官方推薦開發者們使用Pull解析技術。Pull解析技術是第三方開發的開源技術,它同樣可以應用於JavaSE開發。

涉及知識點

  • XmlPullParser 是一個提供對XML進行Pull方式解析的基礎功能的介面。
  • xmlPullParser.getEventType()  返回當前節點的事件類型(如:START_TAG, END_TAG, TEXT, etc.)。
  • xmlPullParser.getName() 獲取當前節點對應的名稱。
  • xmlPullParser.getAttributeCount() 獲取當前節點對應的屬性個數。
  • xmlPullParser.getText() 獲取當前節點對應的文本內容。
  • xmlPullParser.getAttributeName(0) 獲取屬性對應的名稱。
  • xmlPullParser.getAttributeValue(0) 獲取屬性對應的值。
  • xmlPullParser.next() 移動到下一個事件。

Xml文件

Xml存放相對路徑:DemoXml\app\src\main\res\xml\test.xml [xml文件夾]

 1 <bookstore>
 2     <book category="COOKING">
 3         <title lang="en">Everyday Italian</title>
 4         <author>Giada De Laurentiis</author>
 5         <year>2005</year>
 6         <price>30.00</price>
 7     </book>
 8     <book category="CHILDREN">
 9         <title lang="en">Harry Potter</title>
10         <author>J K. Rowling</author>
11         <year>2005</year>
12         <price>29.99</price>
13     </book>
14     <book category="WEB">
15         <title lang="en">Learning XML</title>
16         <author>Erik T. Ray</author>
17         <year>2003</year>
18         <price>39.95</price>
19     </book>
20 </bookstore>

Xml解析源碼

 1 /**
 2      * 獲取Xml內容
 3      * @param resources
 4      * @param id
 5      * @return
 6      * @throws XmlPullParserException
 7      * @throws IOException
 8      */
 9     private List<String> xml_parser(Resources resources, int id) throws XmlPullParserException, IOException {
10         XmlPullParser xmlPullParser = resources.getXml(id);
11         List<String> lstContent=new ArrayList<String>();
12         int eventType = xmlPullParser.getEventType();
13         while (eventType != XmlPullParser.END_DOCUMENT) {
14             switch (eventType) {
15                 case XmlPullParser.START_DOCUMENT://文檔開始
16                     Log.i(TAG, "xml_parser: START_DOCUMENT");
17                     break;
18                 case XmlPullParser.END_DOCUMENT://文檔結束
19                     Log.i(TAG, "xml_parser: END_DOCUMENT");
20                     break;
21                 case XmlPullParser.START_TAG://標記(元素,節點)開始
22                     Log.i(TAG, "xml_parser: START_TAG");
23                     String tagName = xmlPullParser.getName();
24                     //有些節點是沒有屬性值的,所以需要判斷,否則會越界
25                     int count = xmlPullParser.getAttributeCount();//獲取屬性個個數
26                     String tagAttributeValue="";
27                     String tagAttributeName="";
28                     //String text =xmlPullParser.getText();//此處獲取不到text
29                     String content="";
30                     if (count > 0) {
31                         tagAttributeName=xmlPullParser.getAttributeName(0);
32                         tagAttributeValue = xmlPullParser.getAttributeValue(0);
33                         content="標簽="+tagName+"屬性名="+tagAttributeName+"屬性值="+tagAttributeValue;
34                     }else{
35                         content="標簽="+tagName;
36                     }
37                     lstContent.add(content);
38                     break;
39                 case XmlPullParser.TEXT:
40                     String text =xmlPullParser.getText();
41                     lstContent.add("節點內容="+text);
42                     break;
43                 case XmlPullParser.END_TAG://標記結束
44                     Log.i(TAG, "xml_parser: END_TAG");
45                     break;
46             }
47             eventType = xmlPullParser.next();
48         }
49         return lstContent;
50     }

如果Xml文件過大的話,則不適合在Activity主線程中執行,本文是在Worker線程中執行的,如下所示:

 1     private static final String TAG="TAG";
 2 
 3     private static final int MSG_FINISH=0x0001;
 4 
 5     private TextView tvMsg;
 6 
 7     private Handler handler=new Handler(){
 8         @Override
 9         public void handleMessage(Message msg) {
10             switch (msg.what){
11                 case MSG_FINISH:
12                     List<String> lstContent=(List<String>)msg.obj;
13                     for (String info :lstContent){
14                         tvMsg.append(info+"\r\n");
15                     }
16                     break;
17             }
18         }
19     };
20 
21     public void bn_xml_parser_click(View view){
22         tvMsg.setText("");
23         new Thread(){
24             @Override
25             public void run() {
26                 try {
27                     List<String> lstContent=xml_parser(getResources(),R.xml.test);
28                     Message msg=handler.obtainMessage();
29                     msg.what=MSG_FINISH;
30                     msg.obj=lstContent;
31                     handler.sendMessage(msg);
32                 } catch (XmlPullParserException e) {
33                     e.printStackTrace();
34                 } catch (IOException e) {
35                     e.printStackTrace();
36                 }
37             }
38         }.start();
39     }

JSON解析

Json是一種輕量級的數據交換格式,具有良好的可讀和便於快速編寫的特性。業內主流技術為其提供了完整的解決方案,從而可以在不同平臺間進行數據交換。

涉及知識點

  • JSONObject 表示一個Json格式的對象。
  • jsonObject.getString("key"); 獲取字元串格式的值。
  • jsonObject.getInt("key"); 獲取Int類型的值。
  • jsonObject.getBoolean("key"); 獲取bool類型的值。
  • jsonObject.getDouble("key"); 獲取浮點數類型的值。
  • jsonObject.get("key"); 返回Object類型的對象。
  • jsonObject.getJSONArray("key"); 返回數據類型的對象。
  • InputStream 輸入流。

Json文件

Json存放相對路徑:DemoXml\app\src\main\res\raw\test2.json  [raw文件夾]

{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle_school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

Json解析源碼

 1   /**
 2      * 解析到列表
 3      * @return
 4      * @throws IOException
 5      * @throws JSONException
 6      */
 7     private List<String> json_parser() throws IOException, JSONException {
 8         List<String> lstContent = new ArrayList<String>();
 9         String data = getContent(getResources(), R.raw.test2);
10         JSONObject jsonObject = new JSONObject(data);
11         String name = jsonObject.getString("name");
12         int age = jsonObject.getInt("age");
13         boolean gender = jsonObject.getBoolean("gender");
14         double height = jsonObject.getDouble("height");
15         Object grade = jsonObject.get("grade");
16         String middleSchool = jsonObject.getString("middle_school");
17         JSONArray jsonArray = jsonObject.getJSONArray("skills");
18         lstContent.add("name=" + name);
19         lstContent.add("age=" + age);
20         lstContent.add("gender=" + gender);
21         lstContent.add("height=" + height);
22         lstContent.add("grade=" + grade);
23         lstContent.add("middleSchool=" + middleSchool);
24         for (int i = 0; i < jsonArray.length(); i++) {
25             String skill = jsonArray.getString(i);
26             lstContent.add("skill=" + skill);
27         }
28         return lstContent;
29     }
30 
31     /**
32      * 通過id獲取Json文件對應的內容
33      * @param resources
34      * @param id
35      * @return
36      * @throws IOException
37      */
38     private String getContent(Resources resources, int id) throws IOException {
39         StringBuilder stringBuilder = new StringBuilder();
40         InputStream inputStream = null;
41         try {
42             inputStream = resources.openRawResource(id);
43             byte[] bytes = new byte[1024];
44             int length = inputStream.read(bytes, 0, 1024);
45             while (length > -1) {
46                 stringBuilder.append(new String(bytes, 0, length));
47                 length = inputStream.read(bytes, 0, 1024);
48             }
49         } finally {
50             if (inputStream != null) {
51                 inputStream.close();
52             }
53         }
54         return stringBuilder.toString();
55     }

同樣,如果Json文件比較大,或者解析比較慢,則不能在Activity主線程中執行,需要新啟動一個Worker線程,在後臺執行,如下所示:

 1     private static final String TAG="TAG";
 2 
 3     private static final int MSG_FINISH=0x0001;
 4 
 5     private static  final int MSG_SERIALIZE=0x0002;
 6 
 7     private TextView tvMsg;
 8 
 9     private Handler handler=new Handler(){
10         @Override
11         public void handleMessage(Message msg) {
12             switch (msg.what){
13                 case MSG_FINISH:
14                     List<String> lstContent=(List<String>)msg.obj;
15                     for (String info :lstContent){
16                         tvMsg.append(info+"\r\n");
17                     }
18                     break;
19             }
20         }
21     };
22 
23     /**
24      * 解析Json
25      * @param view
26      */
27     public void bn_json_parser_click(View view) {
28         tvMsg.setText("");
29         new Thread() {
30             @Override
31             public void run() {
32                 try {
33                     List<String> lstContent = json_parser();
34                     Message msg = handler.obtainMessage();
35                     msg.what = MSG_FINISH;
36                     msg.obj = lstContent;
37                     handler.sendMessage(msg);
38                 } catch (IOException e) {
39                     e.printStackTrace();
40                 } catch (JSONException e) {
41                     e.printStackTrace();
42                 }
43             }
44         }.start();
45     }

如果需要將Json反序列化成類對象,或者將類對象序列化成Json格式文件,如下是一個幫助類:

  1 package com.hex.demoxml;
  2 
  3 import android.util.Log;
  4 
  5 import java.util.Collection;
  6 import java.lang.reflect.Array;
  7 import java.lang.reflect.Field;
  8 import java.lang.reflect.ParameterizedType;
  9 import java.lang.reflect.Type;
 10 import java.util.Collection;
 11 import org.json.JSONArray;
 12 import org.json.JSONException;
 13 import org.json.JSONObject;
 14 import org.json.JSONStringer;
 15 
 16 /** JSON序列化輔助類 **/
 17 public class JsonHelper {
 18     private static final String TAG="TAG";
 19     /**
 20      * 將對象轉換成Json字元串
 21      **/
 22     public static String toJSON(Object obj) {
 23         JSONStringer js = new JSONStringer();
 24         serialize(js, obj);
 25         return js.toString();
 26     }
 27 
 28     /**
 29      * 序列化為JSON
 30      **/
 31     private static void serialize(JSONStringer js, Object o) {
 32         if (isNull(o)) {
 33             try {
 34                 js.value(null);
 35             } catch (JSONException e) {
 36                 e.printStackTrace();
 37             }
 38             return;
 39         }
 40 
 41         Class<?> clazz = o.getClass();
 42         if (isObject(clazz)) { // 對象
 43             serializeObject(js, o);
 44         } else if (isArray(clazz)) { // 數組
 45             serializeArray(js, o);
 46         } else if (isCollection(clazz)) { // 集合
 47             Collection<?> collection = (Collection<?>) o;
 48             serializeCollect(js, collection);
 49         } else { // 單個值
 50             try {
 51                 js.value(o);
 52             } catch (JSONException e) {
 53                 e.printStackTrace();
 54             }
 55         }
 56     }
 57 
 58     /**
 59      * 序列化數組
 60      **/
 61     private static void serializeArray(JSONStringer js, Object array) {
 62         try {
 63             js.array();
 64             for (int i = 0; i < Array.getLength(array); ++i) {
 65                 Object o = Array.get(array, i);
 66                 serialize(js, o);
 67             }
 68             js.endArray();
 69         } catch (Exception e) {
 70             e.printStackTrace();
 71         }
 72     }
 73 
 74     /**
 75      * 序列化集合
 76      **/
 77     private static void serializeCollect(JSONStringer js, Collection<?> collection) {
 78         try {
 79             js.array();
 80             for (Object o : collection) {
 81                 serialize(js, o);
 82             }
 83             js.endArray();
 84         } catch (Exception e) {
 85             e.printStackTrace();
 86         }
 87     }
 88 
 89     /**
 90      * 序列化對象
 91      **/
 92     private static void serializeObject(JSONStringer js, Object obj) {
 93         try {
 94             js.object();
 95             for (Field f : obj.getClass().getFields()) {
 96                 Object o = f.get(obj);
 97                 js.key(f.getName());
 98                 serialize(js, o);
 99             }
100             js.endObject();
101         } catch (Exception e) {
102             e.printStackTrace();
103         }
104     }
105 
106     /**
107      * 反序列化簡單對象
108      *
109      * @throws
110      **/
111     public static <T> T parseObject(JSONObject jo, Class<T> clazz) {
112         Log.i(TAG, "parseObject: >>>>>>第二個開始");
113         if (clazz == null || isNull(jo)) {
114             Log.i(TAG, "parseObject: >>>>>>第二個parseObject");
115             return null;
116         }
117 
118         T obj = createInstance(clazz);
119         if (obj == null) {
120             Log.i(TAG, "parseObject: >>>>>>創建實例為空");
121             return null;
122         }
123         Log.i(TAG, "parseObject: >>>>>>屬性長度"+clazz.getFields().length);
124         Log.i(TAG, "parseObject: >>>>>>屬性長度2"+clazz.getClass());
125         for (Field f : clazz.getFields()) {
126             Log.i(TAG, "parseObject: >>>>>>"+f.getName());
127             setField(obj, f, jo);
128             //Log.i(TAG, "parseObject: >>>>>>"+obj.);
129         }
130         Log.i(TAG, "parseObject: >>>>>返回obj"+obj.getClass());
131         return obj;
132     }
133 
134     /**
135      * 反序列化簡單對象
136      *
137      * @throws
138      **/
139     public static <T> T parseObject(String jsonString, Class<T> clazz) {
140         if (clazz == null || jsonString == null || jsonString.length() == 0) {
141             Log.i(TAG, "parseObject: >>>>>>>null");
142             return null;
143         }
144         Log.i(TAG, "parseObject: >>>>>>>not null");
145         JSONObject jo = null;
146         try {
147             jo = new JSONObject(jsonString);
148         } catch (JSONException e) {
149             Log.i(TAG, "parseObject: >>>>>>轉換json對象異常:"+e.getMessage());
150             e.printStackTrace();
151         }
152 
153         if (isNull(jo)) {
154             Log.i(TAG, "parseObject: >>>>>轉換後為null");
155             return null;
156         }
157         Log.i(TAG, "parseObject: >>>>>>進入下一步");
158         return parseObject(jo, clazz);
159     }
160 
161     /**
162      * 反序列化數組對象
163      *
164      * @throws
165      **/
166     public static <T> T[] parseArray(JSONArray ja, Class<T> clazz) {
167         if (clazz == null || isNull(ja)) {
168             return null;
169         }
170 
171         int len = ja.length();
172         Log.i(TAG, "parseArray: >>>>>"+len);
173         Log.i(TAG, "parseArray: >>>>>"+clazz.getName());
174         @SuppressWarnings("unchecked")
175         T[] array = (T[]) Array.newInstance(clazz, len);
176 
177         for (int i = 0; i < len; ++i) {
178             try {
179                 Object object=ja.get(i);
180                 if(isSingle(clazz)){
181                     Log.i(TAG, "parseArray: >>>>>:"+object.toString());
182                     array[i]=(T)object.toString();
183                 }else {
184                     JSONObject jo = ja.getJSONObject(i);
185                     Log.i(TAG, "parseArray: >>>>>jo:"+jo.toString());
186                     T o = parseObject(jo, clazz);
187                     Log.i(TAG, "parseArray: >>>>>o:" + o.toString());
188                     array[i] = o;
189                 }
190             } catch (JSONException e) {
191                 e.printStackTrace();
192             }
193         }
194 
195         return array;
196     }
197 
198     /**
199      * 反序列化數組對象
200      *
201      * @throws
202      **/
203     public static <T> T[] parseArray(String jsonString, Class<T> clazz) {
204         if (clazz == null || jsonString == null || jsonString.length() == 0) {
205             return null;
206         }
207         JSONArray jo = null;
208         try {
209             jo = new JSONArray(jsonString);
210         } catch (JSONException e) {
211             e.printStackTrace();
212         }
213 
214         if (isNull(jo)) {
215             return null;
216         }
217 
218         return parseArray(jo, clazz);
219     }
220 
221     /**
222      * 反序列化泛型集合
223      *
224      * @throws
225      **/
226     @SuppressWarnings("unchecked")
227     public static <T> Collection<T> parseCollection(JSONArray ja, Class<?> collectionClazz,
228                                                     Class<T> genericType) {
229 
230         	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、表空間的創建以及刪除 聲明:此操作環境為windows,oracle10G 二、用戶 1.用戶的創建、設置密碼、設置表空間 2、授權 3、刪除用戶 4.解鎖用戶 三、Oracle數據類型(簡單的) 四、簡單DDL(數據定義語言) 1.創建表 2.修改表結構 五、DML(數據操作語言) =》 增刪 ...
  • NGINX lua集成kafka === 第一步:進入opresty目錄 說明:接下來我們關註兩個目錄 "lualib" 和 "nginx" ​ 1.lualib: 是存放opresty所需要的集成軟體包的 ​ 2.nginx: 是nginx服務目錄 接下來,我們進入lualib目錄一看究竟: 這裡 ...
  • jdbc:mysql://localhost:3306/db_film?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8每次把資料庫問好後面的加上,什麼時區問題還是亂碼問題全都解決謝謝! ...
  • NameNode並不會將文件的分塊數據持久化存儲,這些信息會在HDFS啟動時由各個dataNode上報過來。他把這些數據存入記憶體中。並且會定時對記憶體中的數據進行快照。所以對於NameNode節點的機器記憶體應該大一些 ...
  • 背景介紹 我們先來看一下為什麼要做集群,如果我們要部署一個單節點Redis,很明顯會遇到單點故障的問題。 首先能想到解決單點故障的方法,就是做主從,但是當有海量存儲需求時,單一的主從結構就會出問題,說問題之前要先瞭解一下主從之間是如何複製的。 我們把Redis分為三個部分,分別是客戶端、主節點以及從 ...
  • 1、視圖的概念 視圖是關係資料庫系統提供給用戶以多角度觀察資料庫中數據的重要機制。它不僅滿足了各用戶的個性需要,還提供了一種屏蔽未授權數據或無關數據的保護機制,將用戶的處理或查詢操作限定在他有權處理或查詢的數據上。 視圖是從一個或多個基本表和視圖導出的虛表,它只有定義,沒有對應的物理數據。視圖中的內 ...
  • Win7 Eclipse 搭建spark java1.8環境:WordCount helloworld例子 ...
  • 眾所周知, iOS開發找工作越來越難, 企業要求越來越高,一方面是資本寒冬期+七八月是企業招人淡季, 另外一方面也是iOS市場飽和。最近有出去看新機會, 所以下麵記錄一下麵試XimalayaFM的大概過程。 面試一共分為4輪,全程手寫代碼和演算法。 一面:自我介紹, 然後問一下手頭開發App日活和崩潰 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...