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 }
下面我来说说我在使用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 }
自己在使用Pull解析来自服务器的xml文件时。问题的关键在于以下几行代码:
问题出现在了下面这行代码中:
- xmlPullParser.setInput(new StringReader(parseStr.toString()));
正常的使用String类型传入数据时数据可以被读取,但是到了上面的这行代码时就报错。因为个人能力有限,所以具体原因自己没能找出。但是查阅了很多资料后说使用Pull解析时最好将所有数据无论是什么类型,全部转换成InputStream类型,然后再将数据传入Pull中进行解析:
通过上面的InputStream的形式传送到解析器中的数据将不在出现错误,而且以流的形式传入可以设置传入参数的字符集。
总结起来就是:在使用Pull进行解析时,最好的方式是将所有类型的数据都转换成InputStream类型,然后以InputStream的形式进行解析,这样做程序才不会出错。
android使用Pull解析来自服务器的xml文件时出现错误以及解决方案的更多相关文章
- 解析某些特殊格式XML文件时,获取不到根节点问题
还是在语音识别这块.在读取本地的SRGS的XML后,无法获取到根节点<grammar>. 下面是SRGS.XML文件(只给出了根节点) <?xml version="1.0 ...
- 解析流中的Xml文件时,报错:java.net.MalformedURLException: no protocol
原来的代码: // 创建DocumentBuilder对象 DocumentBuilder b = a.newDocumentBuilder(); // 通过DocumentBuilder对象的par ...
- Android使用pull解析xml格式的数据
dom解析:基于全文加载的解析方式 sax解析:基于事件的逐行解析方式 pull解析:同sax XmlPullParser //解析xml文件读取短信内容 ...
- js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中
ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId ...
- python解析xml文件时使用ElementTree和cElementTree的不同点;iter
在python中,解析xml文件时,会选用ElementTree或者cElementTree,那么两者有什么不同呢? 1.cElementTree速度上要比ElementTree快,比较cElemen ...
- 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- Ibatis XML 配置文件注释引起错误及解决方案
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp35 Ibatis XML 配置文件注释引起错误及解决方案 最近在使用Iba ...
- 编辑xml文件时不能自动提示问题的解决
在编辑xml文件时,eclipse总是不能自动提示,在网上找了一些资料,大部分都是说关于xml editor配置的,下面也把这个方法罗列在下面,以供参考: 解决办法:在eclipse的菜单里,找到wi ...
- 项目配置 xml文件时 报错提示(The reference to entity "useSSL" must end with the ';' delimiter.)
这次在配置xml文件时,出现错误提示( The reference to entity “useSSL” must end with the ‘;’ delimiter.) 报错行为 <prop ...
随机推荐
- macbook pro。已经连接上wifi,但是,不能上网的问题
有天,macbook pro关机后,再打开就上不了网了,后面网上看了,说是安装了 lantern出问题,我一想,有次关机lantern是被我强制关掉的.所以再次打开lantern就可以 上网了,然后正 ...
- input 文本框,对中文长度校验
在项目中,经常会遇到,对文本框进行校验. eg. 要求姓名长度为20,中文为10,只能输入中英文. <input maxlength="20" type="t ...
- centos静态绑定IP地址
Centos7 /etc/sysconfig/network-scripts/ifcfg-ens33
- pngencoder图像转换jar
PngEncoder - convert a Java Image to PNGPngEncoderB - convert a Java BufferedImage to PNG Written by ...
- Mysql 单表操作、增删查改(基础4)
新建一个表,往里面插入数据. #新建一个表 mysql> create table test( -> id int, -> name varchar(20) -> );Quer ...
- PHPActiveRecord validates
validates_presence_of #检测是不是为空 为空的话可以抛出异常 *Model类: static $validates_presence_of = array( array('tit ...
- IDEA中配置JUnit单元测试
参考安装教程:https://www.jianshu.com/p/c37753b6dbd6 如果想用junit4的话,需要在pom.xml中配置. 需要安装JUnitGenerator V2.0插件, ...
- 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确
安装好后,登录后台提示 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确 检查mysql是否启动netstat -lnpt是否有3306端口? 一 有A 检查/www/wdlinu ...
- linux下安装kafka
安装条件: 确保zookeeper已经安装成功.zookeeper安装过程见:https://www.cnblogs.com/expiator/p/9853378.html 1.下载kafka 进入A ...
- Local Storage
HTML代码: <ul id="edit" contenteditable="true"> <li>修改我吧,然后刷新页面看看,^_^& ...