• android使用Pull解析来自服务器的xml文件时出现错误以及解决方案


    直接上代码,代码中有详细注释:

     1 public class CheckUpdateManager {
      2     private static final String TAG = "CheckUpdateManager";
      3     private ProgressDialog mWaitDialog;
      4     private Context mContext;
      5     private boolean mIsShowDialog;
      6     private RequestPermissions mCaller;
      7 
      8     public CheckUpdateManager(Context context, Boolean showWaitingDialog) {
      9         this.mContext = context;
     10         this.mIsShowDialog = showWaitingDialog;
     11         if (mIsShowDialog) {
     12             // 创建ProgressDialog对象
     13             mWaitDialog = new ProgressDialog(mContext);
     14             // 设置进度条风格,风格为圆形,旋转的
     15             mWaitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     16             // 设置ProgressDialog 提示信息
     17             mWaitDialog.setMessage("正在检查中,请稍后……");
     18             // 设置ProgressDialog 的进度条是否不明确
     19             mWaitDialog.setIndeterminate(false);
     20             // 设置ProgressDialog可以按返回键取消
     21             mWaitDialog.setCancelable(false);
     22         }
     23     }
     24 
     25     public void setCaller(RequestPermissions caller) {
     26         this.mCaller = caller;
     27     }
     28 
     29     public void checkUpdate() {
     30         if (mIsShowDialog) {
     31             mWaitDialog.show();
     32         }
     33         // 检查接口更新
     34         AsyncHttpClient client = new AsyncHttpClient();
     35         Api api = new Api();
     36         String url = api.version();
     37         client.get(url, new AsyncHttpResponseHandler() {
     38 
     39             @Override
     40             public void onSuccess(int statusCode, Header[] headers,
     41                     byte[] responseString) {
     42                 // TODO Auto-generated method stub
     43                 try {
     44                     //将byte类型转换为String
     45                     String resp = new String(responseString, "utf-8");
     46                     //将String转成InputStream类型
     47                     InputStream str = new ByteArrayInputStream(resp.getBytes());
     48                     //这里调用pull解析的方式
     49                     final ManifestBean bean = parseXmlPull(str);
     50                     SharedPreferences sp = mContext.getSharedPreferences(
     51                             "anhua", Context.MODE_APPEND);
     52                     int old_dianmian = sp.getInt("old_dianmian", 1);// 服务器端默认版本号为1
     53                     if (old_dianmian < Integer.parseInt(bean.getVersion())) {
     54                         // 服务器端版本大于本地版本需要更新
     55                         if ("0".equals(bean.getQiangzhi())) {
     56                             new AlertDialog.Builder(mContext)
     57                                     .setTitle("发现新版本")
     58                                     .setMessage("发现新版本,是否更新?")
     59                                     .setNegativeButton(
     60                                             "取消",
     61                                             new DialogInterface.OnClickListener() {
     62                                                 @Override
     63                                                 public void onClick(
     64                                                         DialogInterface dialogInterface,
     65                                                         int i) {
     66                                                     dialogInterface.dismiss();
     67                                                 }
     68                                             })
     69                                     .setPositiveButton(
     70                                             "确定",
     71                                             new DialogInterface.OnClickListener() {
     72                                                 @Override
     73                                                 public void onClick(
     74                                                         DialogInterface dialogInterface,
     75                                                         int i) {
     76                                                     mCaller.call(bean);
     77                                                 }
     78                                             }).show();
     79                         } else if ("1".equals(bean.getQiangzhi())) {
     80                             mCaller.call(bean);
     81                         }
     82                     } else {
     83                         if (mIsShowDialog) {
     84                             new AlertDialog.Builder(mContext).setTitle("温馨提示")
     85                                     .setMessage("已经是最新版本了!")
     86                                     .setPositiveButton("确定", null).show();
     87                         }
     88                     }
     89                 } catch (UnsupportedEncodingException e) {
     90                     // TODO Auto-generated catch block
     91                     e.printStackTrace();
     92                 }
     93             }
     94 
     95             @Override
     96             public void onFinish() {
     97                 // TODO Auto-generated method stub
     98                 super.onFinish();
     99                 if (mIsShowDialog) {
    100                     mWaitDialog.dismiss();
    101                 }
    102             }
    103 
    104             @Override
    105             public void onFailure(int arg0, Header[] arg1, byte[] arg2,
    106                     Throwable arg3) {
    107                 // TODO Auto-generated method stub
    108                 if (mIsShowDialog) {
    109                     new AlertDialog.Builder(mContext).setTitle("温馨提示")
    110                             .setMessage("网络异常,无法获取版本信息")
    111                             .setPositiveButton("确定", null).show();
    112                 }
    113             }
    114         });
    115     }
    116 
    117     ManifestBean parseXmlPull(InputStream parseStr) {
    118         {
    119             ManifestBean bean = null;
    120             try {
    121                 // 获取XMLPull的解析对象
    122                 XmlPullParserFactory factory = XmlPullParserFactory
    123                         .newInstance();
    124                 XmlPullParser xmlPullParser = factory.newPullParser();
    125                 // 将字节流传送到解析器中
    126                 xmlPullParser.setInput(parseStr, "utf-8");
    127                 
    128                 // xmlPullParser.setInput(new StringReader(parseStr.toString()));
    129                 // 记录下当前的读取事件
    130                 int eventType = xmlPullParser.getEventType();
    131                 // 用来临时记录id和name
    132                 String version = "1";
    133                 String qiangzhi = "0";
    134                 String files = "";
    135                 // 循环读取文档
    136                 while (eventType != XmlPullParser.END_DOCUMENT) {
    137                     // nodeName记录下当前读取的节点的名称
    138                     String nodeName = xmlPullParser.getName();
    139                     switch (eventType) {
    140                     // 根据读取事件来判断执行的操作
    141                     case XmlPullParser.START_DOCUMENT:// 开始文档事件
    142                         // 初始化栈,用来存放读取到的节点的名称,因为该文件中的名称跟id的节点名称是重复的
    143                         // 所以笔者想到了这种办法来控制判断目前读取的是哪一个类型的id和name,当然也有其他方法,读者可以自行试试
    144                         break;
    145                     case XmlPullParser.START_TAG:// 开始元素事件,凡是读取到的是开始节点,该节点名称就入栈
    146                         if ("manifest".equals(xmlPullParser.getName())) {// 取得节点名称并判断
    147                             bean = new ManifestBean();
    148                         } else if ("files".equals(xmlPullParser.getName())) {
    149                             eventType = xmlPullParser.next();
    150                             files = xmlPullParser.getText();
    151                             bean.setFiles(files);
    152                         } else if ("version".equals(xmlPullParser.getName())) {
    153                             eventType = xmlPullParser.next();
    154                             version = xmlPullParser.getText();
    155                             bean.setVersion(version);
    156                         } else if ("qiangzhi".equals(xmlPullParser.getName())) {
    157                             eventType = xmlPullParser.next();
    158                             qiangzhi = xmlPullParser.getText();
    159                             bean.setQiangzhi(qiangzhi);
    160                         } else if ("dianmian".equals(xmlPullParser.getName())) {
    161                             eventType = xmlPullParser.next();
    162                             bean.setDianmian(Integer.parseInt(xmlPullParser
    163                                     .getText()));
    164                         }
    165                         break;
    166                     case XmlPullParser.END_TAG:// 结束元素事件,凡是读取到结束节点则对应的开始元素节点出栈
    167                         if (xmlPullParser.getName().equals("manifest")) {
    168                             return bean;
    169                         }
    170                         break;
    171                     default:
    172                         break;
    173 
    174                     }
    175                     eventType = xmlPullParser.next();// 进入下一个元素并触发相应事件??
    176                 }
    177             } catch (XmlPullParserException e) {
    178                 e.printStackTrace();
    179             } catch (IOException e) {
    180                 e.printStackTrace();
    181             }
    182             return bean;
    183         }
    184     }
    185 
    186     public interface RequestPermissions {
    187         void call(ManifestBean version);
    188     }
    189 
    190 }
    View Code

    下面我来说说我在使用pull解析来自服务器的xml文件时所遇到的问题:

    看一下存在问题的版本:

     1 public class CheckUpdateManager {
      2     private static final String TAG = "CheckUpdateManager";
      3     private ProgressDialog mWaitDialog;
      4     private Context mContext;
      5     private boolean mIsShowDialog;
      6     private RequestPermissions mCaller;
      7 
      8     public CheckUpdateManager(Context context, Boolean showWaitingDialog) {
      9         this.mContext = context;
     10         this.mIsShowDialog = showWaitingDialog;
     11         if (mIsShowDialog) {
     12             // 创建ProgressDialog对象
     13             mWaitDialog = new ProgressDialog(mContext);
     14             // 设置进度条风格,风格为圆形,旋转的
     15             mWaitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
     16             // 设置ProgressDialog 提示信息
     17             mWaitDialog.setMessage("正在检查中,请稍后……");
     18             // 设置ProgressDialog 的进度条是否不明确
     19             mWaitDialog.setIndeterminate(false);
     20             // 设置ProgressDialog可以按返回键取消
     21             mWaitDialog.setCancelable(false);
     22         }
     23     }
     24 
     25     public void setCaller(RequestPermissions caller) {
     26         this.mCaller = caller;
     27     }
     28 
     29     public void checkUpdate() {
     30         if (mIsShowDialog) {
     31             mWaitDialog.show();
     32         }
     33         // 检查接口更新
     34         AsyncHttpClient client = new AsyncHttpClient();
     35         Api api = new Api();
     36         String url = api.version();
     37         client.get(url, new AsyncHttpResponseHandler() {
     38 
     39             @Override
     40             public void onSuccess(int statusCode, Header[] headers,
     41                     byte[] responseString) {
     42                 // TODO Auto-generated method stub
     43                 try {
     44                     //将byte类型转换为String
     45                     String resp = new String(responseString, "utf-8");
     46                     //将String转成InputStream类型
     47 //                    InputStream str = new ByteArrayInputStream(resp.getBytes());
     48                     //这里调用pull解析的方式
     49                     final ManifestBean bean = parseXmlPull(resp);
     50                     SharedPreferences sp = mContext.getSharedPreferences(
     51                             "anhua", Context.MODE_APPEND);
     52                     int old_dianmian = sp.getInt("old_dianmian", 1);// 服务器端默认版本号为1
     53                     if (old_dianmian < Integer.parseInt(bean.getVersion())) {
     54                         // 服务器端版本大于本地版本需要更新
     55                         if ("0".equals(bean.getQiangzhi())) {
     56                             new AlertDialog.Builder(mContext)
     57                                     .setTitle("发现新版本")
     58                                     .setMessage("发现新版本,是否更新?")
     59                                     .setNegativeButton(
     60                                             "取消",
     61                                             new DialogInterface.OnClickListener() {
     62                                                 @Override
     63                                                 public void onClick(
     64                                                         DialogInterface dialogInterface,
     65                                                         int i) {
     66                                                     dialogInterface.dismiss();
     67                                                 }
     68                                             })
     69                                     .setPositiveButton(
     70                                             "确定",
     71                                             new DialogInterface.OnClickListener() {
     72                                                 @Override
     73                                                 public void onClick(
     74                                                         DialogInterface dialogInterface,
     75                                                         int i) {
     76                                                     mCaller.call(bean);
     77                                                 }
     78                                             }).show();
     79                         } else if ("1".equals(bean.getQiangzhi())) {
     80                             mCaller.call(bean);
     81                         }
     82                     } else {
     83                         if (mIsShowDialog) {
     84                             new AlertDialog.Builder(mContext).setTitle("温馨提示")
     85                                     .setMessage("已经是最新版本了!")
     86                                     .setPositiveButton("确定", null).show();
     87                         }
     88                     }
     89                 } catch (UnsupportedEncodingException e) {
     90                     // TODO Auto-generated catch block
     91                     e.printStackTrace();
     92                 }
     93             }
     94 
     95             @Override
     96             public void onFinish() {
     97                 // TODO Auto-generated method stub
     98                 super.onFinish();
     99                 if (mIsShowDialog) {
    100                     mWaitDialog.dismiss();
    101                 }
    102             }
    103 
    104             @Override
    105             public void onFailure(int arg0, Header[] arg1, byte[] arg2,
    106                     Throwable arg3) {
    107                 // TODO Auto-generated method stub
    108                 if (mIsShowDialog) {
    109                     new AlertDialog.Builder(mContext).setTitle("温馨提示")
    110                             .setMessage("网络异常,无法获取版本信息")
    111                             .setPositiveButton("确定", null).show();
    112                 }
    113             }
    114         });
    115     }
    116 
    117     ManifestBean parseXmlPull(String parseStr) {
    118         {
    119             ManifestBean bean = null;
    120             try {
    121                 // 获取XMLPull的解析对象
    122                 XmlPullParserFactory factory = XmlPullParserFactory
    123                         .newInstance();
    124                 XmlPullParser xmlPullParser = factory.newPullParser();
    125                 // 将字节流传送到解析器中
    126 //                xmlPullParser.setInput(parseStr, "utf-8");
    127                 
    128                  xmlPullParser.setInput(new StringReader(parseStr.toString()));
    129                 // 记录下当前的读取事件
    130                 int eventType = xmlPullParser.getEventType();
    131                 // 用来临时记录id和name
    132                 String version = "1";
    133                 String qiangzhi = "0";
    134                 String files = "";
    135                 // 循环读取文档
    136                 while (eventType != XmlPullParser.END_DOCUMENT) {
    137                     // nodeName记录下当前读取的节点的名称
    138                     String nodeName = xmlPullParser.getName();
    139                     switch (eventType) {
    140                     // 根据读取事件来判断执行的操作
    141                     case XmlPullParser.START_DOCUMENT:// 开始文档事件
    142                         // 初始化栈,用来存放读取到的节点的名称,因为该文件中的名称跟id的节点名称是重复的
    143                         // 所以笔者想到了这种办法来控制判断目前读取的是哪一个类型的id和name,当然也有其他方法,读者可以自行试试
    144                         break;
    145                     case XmlPullParser.START_TAG:// 开始元素事件,凡是读取到的是开始节点,该节点名称就入栈
    146                         if ("manifest".equals(xmlPullParser.getName())) {// 取得节点名称并判断
    147                             bean = new ManifestBean();
    148                         } else if ("files".equals(xmlPullParser.getName())) {
    149                             eventType = xmlPullParser.next();
    150                             files = xmlPullParser.getText();
    151                             bean.setFiles(files);
    152                         } else if ("version".equals(xmlPullParser.getName())) {
    153                             eventType = xmlPullParser.next();
    154                             version = xmlPullParser.getText();
    155                             bean.setVersion(version);
    156                         } else if ("qiangzhi".equals(xmlPullParser.getName())) {
    157                             eventType = xmlPullParser.next();
    158                             qiangzhi = xmlPullParser.getText();
    159                             bean.setQiangzhi(qiangzhi);
    160                         } else if ("dianmian".equals(xmlPullParser.getName())) {
    161                             eventType = xmlPullParser.next();
    162                             bean.setDianmian(Integer.parseInt(xmlPullParser
    163                                     .getText()));
    164                         }
    165                         break;
    166                     case XmlPullParser.END_TAG:// 结束元素事件,凡是读取到结束节点则对应的开始元素节点出栈
    167                         if (xmlPullParser.getName().equals("manifest")) {
    168                             return bean;
    169                         }
    170                         break;
    171                     default:
    172                         break;
    173 
    174                     }
    175                     eventType = xmlPullParser.next();// 进入下一个元素并触发相应事件??
    176                 }
    177             } catch (XmlPullParserException e) {
    178                 e.printStackTrace();
    179             } catch (IOException e) {
    180                 e.printStackTrace();
    181             }
    182             return bean;
    183         }
    184     }
    185 
    186     public interface RequestPermissions {
    187         void call(ManifestBean version);
    188     }
    View Code

    自己在使用Pull解析来自服务器的xml文件时。问题的关键在于以下几行代码:

    问题出现在了下面这行代码中:

    xmlPullParser.setInput(new StringReader(parseStr.toString()));

    正常的使用String类型传入数据时数据可以被读取,但是到了上面的这行代码时就报错。因为个人能力有限,所以具体原因自己没能找出。但是查阅了很多资料后说使用Pull解析时最好将所有数据无论是什么类型,全部转换成InputStream类型,然后再将数据传入Pull中进行解析:

    通过上面的InputStream的形式传送到解析器中的数据将不在出现错误,而且以流的形式传入可以设置传入参数的字符集。

    总结起来就是:在使用Pull进行解析时,最好的方式是将所有类型的数据都转换成InputStream类型,然后以InputStream的形式进行解析,这样做程序才不会出错。

  • 相关阅读:
    uva 10129 poj 1386 hdu 1116 zoj 2016 play on words
    redis持久化
    Redis事务
    非阻塞I/O多路复用机制
    SFTP
    FTP
    http协议特点及session共享及单点登录
    什么是cookie以及cookie的特性、优缺点
    异步IO和同步IO的区别:
    TCP操作与原理
  • 原文地址:https://www.cnblogs.com/1925yiyi/p/7444226.html
Copyright © 2020-2023  润新知