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 ...
随机推荐
- Python系列之 __new__ 与 __init__
很喜欢Python这门语言.在看过语法后学习了Django 这个 Web 开发框架.算是对 Python 有些熟悉了.不过对里面很多东西还是不知道,因为用的少.今天学习了两个魔术方法:__new__ ...
- linux下的arm汇编程序
1.gnu 的编译环境搭建 解压编译工具,加入环境变量PATH 2.编译相关命令的使用 编译命令 arm-linux-gcc -g -c -o led.o main.o led.c main.c / ...
- 手机端head部分
<!doctype html> <html lang="zh"> <head> <meta charset="utf-8&quo ...
- 微信小程序如何提交审核并发布?发布问题:小程序只支持https访问
http://www.jisuapp.cn/news/305.html 发布问题:1.小程序只支持https访问 2.要配置服务域名
- 在maven中classpath notfund
- Oracle数据导出导入
总结了几种Oracle导入导出的命令方法,方便以后使用. 数据导出: 1. 将数据库test完全导出,用户名system 密码manager 导出到d:/daochu.dmp中 ...
- python学习day5 常量 运算符补充 流程控制基础
1.常量 值不会改变的量 python中没有特别的语法定义常量,一般约定用全大写字母命名常量,比如圆周率pi 2.预算符补充 2.1算数运算符 print(10/3)除法运算 print(10//3) ...
- zabbix监测公网IP的客户端主机
未经测试 如果server端是内网的主机,需要注意:防火墙.端口映射 再用zabbix服务器去Telnet客户机的10050端口,然后在客户机中查看10050被什么ip访问了,拿到这个ip之后,加到之 ...
- Linux下安装和使用nginx
浏览器和服务器的关系 NGINX nginx是什么 nginx是一个开源的,支持高性能,高并发的www服务和代理服务软件. nginx不但是一个优秀的web服务软件,还可以作为反向代理,负载均衡,以及 ...
- java深拷贝与浅拷贝
1.调用Object类的clone方法必须实现Cloneable接口,clone属于浅拷贝. 2.可以通过java的反序列化机制进行深拷贝. 3.可以直接用apache提供的一些包进行深拷贝和浅拷贝, ...