• Android中Xml工具类的封装


      Android中经常使用到操作XML,其中有一对XmlSerializer和XmlPullParser封装的很好,可是操作起来很复杂,虽然不难,但是感觉做了一点小事却写了一大堆的代码。有点烦,因此封装一下。

      其思路为:根据传入的数据,获取字节码后进行反射解析,然后在存储。思路很简单,此demo只写了一个基本的List<T>类型的,其它类型道理与此大同小异,就当这个是抛砖引玉了。

      对于一些Model可能有些字段是不需要序列化的,这里可以使用注解来操作

    /**
     * XML操作工具类
     * @author chenhao24
     *
     */
    public class XMLUtils{
        
        public interface XMLProgressCallback{
            void onBefore(List<?> data);
            void onProgress(int index);
            void onFinished();
        }
        
        /**
         * 解析XML数据
         * @param path
         * @param clazz
         * @return
         */
        public static List<Object> pullParserData(String path, Class<?> clazz,XMLProgressCallback callback){
    
            if (clazz == null || path == null || TextUtils.isEmpty(path)) {
                return null;
            }
    
            File destFile = new File(path);
            
            if(! destFile.exists()){
                return null;
            }
            
            List<Object> resData = null;
    
            Map<String, Method> mdatas = new HashMap<String, Method>();
    
            String[] classNames = parseFields(clazz, mdatas, StaticDatas.METHOD_SET);
            
            List<Object> data = queryData(destFile, resData, mdatas, classNames);
            
            callback.onBefore(data);
            
            return data;
        }
        
        /**
         * 从XML中读取数据
         * @param destFile
         * @param resData
         * @param mdatas
         * @param classNames
         * @return
         */
        private static List<Object> queryData(File destFile, List<Object> resData,Map<String, Method> mdatas, String[] classNames) {
            
            XmlPullParser pullParser = Xml.newPullParser();
    
            InputStream inputStream;
    
            try {
                inputStream = new FileInputStream(destFile);
    
                pullParser.setInput(inputStream, StaticDatas.UTF8);
    
                int eventType = pullParser.getEventType();
                
                Object obj = null;
    
                while (eventType != XmlPullParser.END_DOCUMENT) {
                    String tagName = pullParser.getName();
    
                    if (eventType == XmlPullParser.START_TAG) {
                        if (tagName.equals(StaticDatas.XML_ROOT)) {
                            resData = new ArrayList<Object>();
                            eventType = pullParser.next();
                            continue;
                        }
    
                        if (tagName.equals(classNames[0])) {
                            obj = Class.forName(classNames[1]).newInstance();
                            eventType = pullParser.next();
                            continue;
                        }
    
                        for (Iterator<Entry<String, Method>> iter = mdatas.entrySet().iterator(); iter.hasNext();) {
                            Entry<String, Method> entry = iter.next();
    
                            String key = entry.getKey();
    
                            if(key.equals(tagName)){
                                Method method = entry.getValue();
                                method.invoke(obj, pullParser.nextText());
                            }
                        }
                    }
    
                    if (eventType == XmlPullParser.END_TAG) {
                        if (tagName.equals(classNames[0])) {
                            resData.add(obj);
                        }
                    }
    
                    eventType = pullParser.next();
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            return resData;
        }
        
        /**
         * 持久化数据到本地xml
         * @param path
         * @param data
         * @throws Exception
         */
        public static void serializerData(String path,List<?> data,XMLProgressCallback callback){
            if(data == null || path == null || TextUtils.isEmpty(path) || data.isEmpty()){
                return;
            }
            
            callback.onBefore(data);
            
            File destFile = new File(path);
            
            try {
                if(destFile.exists()){
                    destFile.delete();
                    destFile.createNewFile();
                }
                
                Map<String, Method> mdatas = new HashMap<String, Method>();
                
                String className = parseFields(data,mdatas,StaticDatas.METHOD_GET)[0];
                
                insertData(mdatas,data,destFile,className,callback);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            callback.onFinished();
        }
        
        
        
        /**
         * 解析字段和Get方法
         * @param clazz
         * @param mdatas
         * @return
         */
        private static String[] parseFields(Class<?> clazz,Map<String, Method> mdatas,String methodType) {
            
            Field[] fields = clazz.getDeclaredFields();
    
            Method[] methods = clazz.getMethods();
            
            for (Field field : fields) {
                String fieldName = field.getName().toLowerCase(Locale.ENGLISH);
                for (Method method : methods) {
                    //转小写
                    String methodName = method.getName().toLowerCase(Locale.ENGLISH);
                    
                    // 根据 field和get匹配
                    if (methodName.startsWith(methodType)
                            && methodName.endsWith(fieldName)) {
                        mdatas.put(fieldName, method);
                    } else {
                        continue;
                    }
                }
            }
            
            String clazzName = clazz.getName();
            
            return new String[]{clazzName.substring(clazzName.lastIndexOf(".") + 1).toLowerCase(Locale.ENGLISH),clazzName};
        }
    
        /**
         * 获取字节码并解析出字段和该字段对应的get方法
         * @param data
         * @param mdatas
         * @return
         */
        private static String[] parseFields(List<?> data,Map<String, Method> mdatas,String methodType) {
            Class<?> clazz = data.get(0).getClass();
            return parseFields(clazz,mdatas,methodType);
        }
        
        /**
         * 对数据进行解析并存储到xml中
         * 这个方法写的不好,解析类和操作XML的代码混合在一起
         * 而且还有个 双重循环。暂时先不处理
         * @param mdatas
         * @param data
         * @param destFile
         * @param clazzName
         * @throws Exception
         */
        private static void insertData(Map<String, Method> mdatas,List<?> data,File destFile,String clazzName,XMLProgressCallback callback) throws Exception{
            
            // 此处进行存储
            XmlSerializer xmlCreater = Xml.newSerializer();
            
            FileOutputStream outputStream = new FileOutputStream(destFile);
            
            xmlCreater.setOutput(outputStream, StaticDatas.UTF8);
            
            xmlCreater.startDocument(StaticDatas.UTF8, true);
            
            // XML_ROOT 常量 写死 的 根节点 list
            xmlCreater.startTag(null, StaticDatas.XML_ROOT);
            
            for (Object mtmp : data) {
                // 此处开始循环创建
                xmlCreater.startTag(null, clazzName);
                
                int index = 0;
                
                for (Iterator<Entry<String, Method>> iter = mdatas.entrySet().iterator(); iter.hasNext();) {
                    callback.onProgress(++ index);
                    
                    Entry<String, Method> entry = iter.next();
                    String key = entry.getKey();
                    Method method = entry.getValue();
                    Object obj = method.invoke(mtmp, new Object[]{});
                    
                    xmlCreater.startTag(null, key);
                    xmlCreater.text(obj.toString());
                    xmlCreater.endTag(null, key);
                }
                
                // 循环创建结束
                xmlCreater.endTag(null, clazzName);
            }
            
            xmlCreater.endTag(null, StaticDatas.XML_ROOT);
            
            xmlCreater.endDocument();
            
            xmlCreater.flush();
            
            if(outputStream != null){
                outputStream.close();
            }
            
            xmlCreater = null;
        }
    }
  • 相关阅读:
    SEO值得学习建议
    ClientValidationFunction
    readystate的五种状态
    XMLHTTP对象参考
    Provider详解
    有缺点,向左走向右走
    DotNetBar 6.6.0.4 for Vs2005 (+特殊补丁)
    [无敌]一些web开发中常用的、做成cs文件的js代码 转帖来的
    AjaxPro.NET框架生成高效率的Tree(Asp.net 2.0)(示例代码下载)
    Vista 下使用Visual Studio 2005 开发Oracle 方面程序出现的数据连结问题及解决方案
  • 原文地址:https://www.cnblogs.com/cbooy/p/4965073.html
Copyright © 2020-2023  润新知