一起学Android之Xml与Json解析

概述 在网络中,数据交互通常是以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存放相对路径:DemoXmlappsrcmainresxmltest.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+"rn");
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存放相对路径:DemoXmlappsrcmainresrawtest2.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+"rn");
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         
                    
  • 发表于 2019-08-06 14:20
  • 阅读 ( 322 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除