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 引用和对象理解(转)
引用和对象分离 从最开始的变量开始思考: 在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可 (这个和C语言等静态类型语言不同,和python为动态类型有关 ...
- js高级-变量内存分析
var a = 9, b, c={age:9}, d; b = a; b = 19; console.log(a) console.log(b) d = c; d.age = 22; console ...
- 构建缓存gradle
结合Kotlin使用Gradle build cache 宛丘之上兮 关注 2018.03.11 00:21* 字数 1177 阅读 505评论 5喜欢 4 在2017年4月,Gradle发布了bui ...
- Java http请求工具类
该工具类可以调用POST请求或者Get请求,参数以Map的方式传入,支持获获取返回值,返回值接收类型为String HttpRequestUtil.java package com.util; imp ...
- 03_java基础(四)之方法的创建与调用
import org.junit.Test; public class Main { public static void main(String[] args) { System.out.print ...
- CGLIB代理基础
本文意在讲解CGLIB的基础使用及基本原理. 一.CGLIB的基本原理: 依赖ASM字节码工具,通过动态生成实现接口或继承类的类字节码,实现动态代理. 针对接口,生成实现接口的类,即implement ...
- 《java与模式》阅读笔记01
这次我读了前两章的内容,就如书名所言,这本书主要将的就是java中的模式,在书中的序言就把所有的模式都介绍了一下,主要有, 1.创建模式:简单工厂模式,工厂方法模式,抽象工厂模式,建造模式 2.行为模 ...
- python return 及lambda函数
return有两个作用: 1.用来返回函数的运行结果,或者调用另外一个函数.比如max()函数 >>> def fun(a,b): #返回函数结果. return max(a,b) ...
- ss源码学习--从协议建立到完成一次代理请求
上一次介绍了ss源码中各个事件处理函数完成的工作,这次具体分析一下协议的建立以及请求数据的传输过程. 因为ss的local和server共用一个类以及一系列的事件处理函数,所以看起来稍显复杂.下面来将 ...
- 如何向 Windows 7 镜像中添加 USB3.0 驱动
如何向 Windows 7 镜像中添加 USB3.0 驱动 1. Microsoft 在 Windows 7 的安装光盘并没有集成各个厂商的 USB3.0 驱动,可 以使用下面方法添加 USB3.0 ...