Android XML小工具   一、概述     XML与Object互相转化,支持8种基本类型、String和byte[]。byte[]需要经由base64编码(API8以后才有,之前版本可以自己拷入)。     更多代码及测试用例,见附件工程!   二、Object –> XML  
            
  1. public class XmlBuilder {  
  2.  
  3.     /**  
  4.      * 由对象属性生成XML  
  5.      *   
  6.      * @param outs 输出流  
  7.      * @param encoding 字符编码  
  8.      * @param obj 对象  
  9.      */ 
  10.     public void buildXml(OutputStream outs, String encoding, Object obj)  
  11.             throws IllegalArgumentException, IllegalStateException,  
  12.             IOException, IllegalAccessException {  
  13.         XmlSerializer serializer = Xml.newSerializer(); // 创建一个Xml序列化  
  14.         serializer.setOutput(outs, encoding); // 设置输出流及字符编码  
  15.         serializer.startDocument(encoding, true); // 开始文档  
  16.         writeXml(serializer, obj); // 写文档  
  17.         serializer.endDocument(); // 结束文档  
  18.         outs.close(); // 关闭输出流  
  19.     }  
  20.  
  21.     /**  
  22.      * 将对象属性写入XML  
  23.      *   
  24.      * @param serializer XML序列化  
  25.      * @param obj 对象  
  26.      */ 
  27.     private void writeXml(XmlSerializer serializer, Object obj)  
  28.             throws IllegalArgumentException, IllegalStateException,  
  29.             IOException, IllegalAccessException {  
  30.  
  31.         final String tag_type = "type";  
  32.         final String tag_value = "value";  
  33.  
  34.         Class<?> cls = obj.getClass(); // 获取对象运行时类  
  35.         String clsName = cls.getName(); // 获取对象名称  
  36.  
  37.         serializer.startTag(null, clsName);  
  38.  
  39.         Field[] fields = cls.getDeclaredFields(); // 返回类声明的所有字段  
  40.  
  41.         boolean isWrite;  
  42.         Class<?> type; // 变量类型  
  43.         String varName, typeName, value = null// 变量名、类型名、变量值  
  44.         for (Field field : fields) {  
  45.             isWrite = true;  
  46.             type = field.getType(); // 获取变量类型  
  47.             typeName = type.getName(); // 获取类型名  
  48.             field.setAccessible(true); // 设置变量可访问  
  49.             if (type.isPrimitive()) { // 是否为基本类型  
  50.                 if (typeName.equals("boolean")) {  
  51.                     value = String.valueOf(field.getBoolean(obj));  
  52.                 } else if (typeName.equals("char")) {  
  53.                     // char型未赋值,为默认'\u0000'时,会影响parser.next()  
  54.                     char c = field.getChar(obj);  
  55.                     value = c == '\u0000' ? "null" : String.valueOf(field  
  56.                             .getChar(obj));  
  57.                 } else if (typeName.equals("byte")) {  
  58.                     value = String.valueOf(field.getByte(obj));  
  59.                 } else if (typeName.equals("short")) {  
  60.                     value = String.valueOf(field.getShort(obj));  
  61.                 } else if (typeName.equals("int")) {  
  62.                     value = String.valueOf(field.getInt(obj));  
  63.                 } else if (typeName.equals("long")) {  
  64.                     value = String.valueOf(field.getLong(obj));  
  65.                 } else if (typeName.equals("float")) {  
  66.                     value = String.valueOf(field.getFloat(obj));  
  67.                 } else if (typeName.equals("double")) {  
  68.                     value = String.valueOf(field.getDouble(obj));  
  69.                 }  
  70.             } else if (typeName.equals("java.lang.String")) { // 是否为String  
  71.                 value = field.get(obj) == null ? "null" : field.get(obj)  
  72.                         .toString();  
  73.             } else if (typeName.equals("[B")) { // 是否为byte[]  
  74.                 typeName = getTypeHelper(type); // 字符代码->[]形式  
  75.                 // 用Base64将byte[]转成字符串(SDK 2.2之后自带)  
  76.                 value = field.get(obj) == null ? "null" 
  77.                         : Base64.encodeToString((byte[]) field.get(obj),  
  78.                                 Base64.DEFAULT);  
  79.             } else { // 其他类型暂不需要  
  80.                 isWrite = false;  
  81.             }  
  82.             if (isWrite) {  
  83.                 varName = field.getName(); // 获取变量名  
  84.                 serializer.startTag(null, varName);  
  85.                 writeTag(serializer, tag_type, typeName);  
  86.                 writeTag(serializer, tag_value, value);  
  87.                 serializer.endTag(null, varName);  
  88.             }  
  89.         }  
  90.  
  91.         serializer.endTag(null, clsName);  
  92.     }  
  93.  
  94.     /**  
  95.      * 字符代码->[]形式  
  96.      */ 
  97.     private String getTypeHelper(Class<?> type) {  
  98.         if (type.isArray()) {  
  99.             Class<?> c = type.getComponentType();  
  100.             return getTypeHelper(c) + "[]";  
  101.         } else {  
  102.             return type.getName();  
  103.         }  
  104.     }  
  105.  
  106.     /**  
  107.      * 写一个标签及值  
  108.      */ 
  109.     private void writeTag(XmlSerializer serializer, String tag, String value)  
  110.             throws IllegalArgumentException, IllegalStateException, IOException {  
  111.         serializer.startTag(null, tag);  
  112.         serializer.text(value);  
  113.         serializer.endTag(null, tag);  
  114.     }  
  115.  
  三、XML -> Object  
            
  1. public class XmlParser {  
  2.  
  3.     /**  
  4.      * 分析XML将对应值赋予对象  
  5.      *   
  6.      * @param ins 输入流  
  7.      * @param encoding 字符编码  
  8.      * @param obj 对象  
  9.      */ 
  10.     public void parseXml(InputStream ins, String encoding, Object obj)  
  11.             throws XmlPullParserException, IllegalArgumentException,  
  12.             UnsupportedEncodingException, IllegalAccessException, IOException {  
  13.         XmlPullParser parser = Xml.newPullParser(); // 创建一个Xml分析器  
  14.         parser.setInput(ins, encoding); // 设置输入流及字符编码  
  15.         parseXml(parser, obj); // 解析文档  
  16.         ins.close(); // 关闭输入流  
  17.     }  
  18.  
  19.     /**  
  20.      * 分析XML详细步骤  
  21.      *   
  22.      * @param parser Xml分析器  
  23.      * @param obj 对象  
  24.      */ 
  25.     private void parseXml(XmlPullParser parser, Object obj)  
  26.             throws XmlPullParserException, IllegalArgumentException,  
  27.             UnsupportedEncodingException, IllegalAccessException, IOException {  
  28.  
  29.         final String tag_value = "value";  
  30.  
  31.         Class<?> cls = obj.getClass(); // 获取对象运行时类  
  32.         String clsName = cls.getName(); // 获取对象名称  
  33.  
  34.         Field[] fields = cls.getDeclaredFields(); // 返回类声明的所有字段  
  35.  
  36.         Field field = null;  
  37.  
  38.         int tagDepth; // 标签深度  
  39.         String tagName; // 标签名称  
  40.         int eventType = parser.getEventType(); // 获取事件类型  
  41.         while (true) {  
  42.             if (eventType == XmlPullParser.START_DOCUMENT) {  
  43.                 // Log.i("START_DOCUMENT", "=START_DOCUMENT");  
  44.             } else if (eventType == XmlPullParser.START_TAG) {  
  45.                 // Log.i("START_TAG", "=START_TAG");  
  46.  
  47.                 tagDepth = parser.getDepth(); // 获取标签深度  
  48.                 tagName = parser.getName(); // 获取标签名称  
  49.  
  50.                 if (tagDepth == 1) { // 一级标签  
  51.                     if (!tagName.equals(clsName)) { // 与对象名称不一致时  
  52.                         throw new XmlPullParserException("XML首标签名与对象名称不一致");  
  53.                     }  
  54.                 } else if (tagDepth == 2) { // 二级标签  
  55.                     // 判断标签名称是否符合类的某一字段名称  
  56.                     field = hasField(tagName, fields);  
  57.                 } else if (tagDepth == 3 && field != null) { // 三级标签  
  58.                     if (tagName.equals(tag_value)) { // 如果是value标签  
  59.                         setValue(obj, field, parser.nextText());  
  60.                         field = null;  
  61.                     }  
  62.                 }  
  63.             } else if (eventType == XmlPullParser.END_TAG) {  
  64.                 // Log.i("END_TAG", "=END_TAG");  
  65.             } else if (eventType == XmlPullParser.TEXT) {  
  66.                 // Log.i("TEXT", "=TEXT");  
  67.             } else if (eventType == XmlPullParser.END_DOCUMENT) {  
  68.                 // Log.i("END_DOCUMENT", "=END_DOCUMENT");  
  69.                 break;  
  70.             }  
  71.             eventType = parser.next(); // 下一解析事件  
  72.         }  
  73.     }  
  74.  
  75.     /**  
  76.      * 判断标签名称是否符合类的某一字段名称  
  77.      *   
  78.      * @param tagName 标签名称  
  79.      * @param fields 类字段集合  
  80.      * @return 符合:Field;否则:null  
  81.      */ 
  82.     private Field hasField(String tagName, Field[] fields) {  
  83.         for (Field field : fields) {  
  84.             if (tagName.equals(field.getName())) {  
  85.                 return field;  
  86.             }  
  87.         }  
  88.         return null;  
  89.     }  
  90.  
  91.     /**  
  92.      * 给字段设值  
  93.      *   
  94.      * @param obj 对象  
  95.      * @param field 字段  
  96.      * @param value 值  
  97.      */ 
  98.     private void setValue(Object obj, Field field, String value)  
  99.             throws IllegalArgumentException, IllegalAccessException,  
  100.             UnsupportedEncodingException {  
  101.         Class<?> type = field.getType(); // 变量类型  
  102.         String typeName = type.getName(); // 类型名  
  103.         field.setAccessible(true); // 设置变量可访问  
  104.         if (type.isPrimitive()) { // 是否为基本类型  
  105.             if (typeName.equals("boolean")) {  
  106.                 field.setBoolean(obj, Boolean.parseBoolean(value));  
  107.             } else if (typeName.equals("char")) {  
  108.                 if (!value.equals("null")) {  
  109.                     field.setChar(obj, value.charAt(0));  
  110.                 }  
  111.             } else if (typeName.equals("byte")) {  
  112.                 field.setByte(obj, Byte.parseByte(value));  
  113.             } else if (typeName.equals("short")) {  
  114.                 field.setShort(obj, Short.parseShort(value));  
  115.             } else if (typeName.equals("int")) {  
  116.                 field.setInt(obj, Integer.parseInt(value));  
  117.             } else if (typeName.equals("long")) {  
  118.                 field.setLong(obj, Long.parseLong(value));  
  119.             } else if (typeName.equals("float")) {  
  120.                 field.setFloat(obj, Float.parseFloat(value));  
  121.             } else if (typeName.equals("double")) {  
  122.                 field.setDouble(obj, Double.parseDouble(value));  
  123.             }  
  124.         } else if (typeName.equals("java.lang.String")) { // 是否为String  
  125.             if (!value.equals("null")) {  
  126.                 field.set(obj, value);  
  127.             }  
  128.         } else if (typeName.equals("[B")) { // 是否为byte[]  
  129.             if (!value.equals("null")) {  
  130.                 // 用Base64将字符串转成byte[](SDK 2.2之后自带)  
  131.                 field.set(obj, Base64.decode(value, Base64.DEFAULT));  
  132.             }  
  133.         } // 其他类型暂不需要  
  134.     }  
  135.  
  四、后记     Json与Object互相转化,可看《 Android实时绘制效果》附件工程内的JsonUtil。

更多相关文章

  1. Struts2中一流的方式输出
  2. ActivityManagerService启动流程详解
  3. Android消息机制(Handler、Looper、MessageQueue)
  4. Android的Application对象讲解
  5. 阿里架构师最新整理 Android(安卓)面试点梳理,你收藏了吗?
  6. 详解Android(安卓)Handler的使用-别说你不懂handler
  7. Android中关于JNI 的学习(二)对于JNI方法名,数据类型和方法签名的一
  8. Android中各个Activity中数据的传递
  9. Android用户界面——通用布局对象

随机推荐

  1. android注意事项。随时补充
  2. Android(安卓)TCP socket通信
  3. 安卓广播监听USB插拔
  4. GridView属性集合 drawSelectorOnTop
  5. Android(安卓)之ActivityThead、Activity
  6. Android setContentView方法解析(一)
  7. android 三级联动开源框架用法
  8. Android中使用PULL方式解析XML文件深入介
  9. Android学习笔记(29):搜索框SearchView
  10. Android(安卓)Rxjava+Retrofit网络请求框