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

 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文件时出现错误以及解决方案的更多相关文章

  1. 解析某些特殊格式XML文件时,获取不到根节点问题

    还是在语音识别这块.在读取本地的SRGS的XML后,无法获取到根节点<grammar>. 下面是SRGS.XML文件(只给出了根节点) <?xml version="1.0 ...

  2. 解析流中的Xml文件时,报错:java.net.MalformedURLException: no protocol

    原来的代码: // 创建DocumentBuilder对象 DocumentBuilder b = a.newDocumentBuilder(); // 通过DocumentBuilder对象的par ...

  3. Android使用pull解析xml格式的数据

    dom解析:基于全文加载的解析方式   sax解析:基于事件的逐行解析方式  pull解析:同sax              XmlPullParser     //解析xml文件读取短信内容    ...

  4. js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中

    ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId ...

  5. python解析xml文件时使用ElementTree和cElementTree的不同点;iter

    在python中,解析xml文件时,会选用ElementTree或者cElementTree,那么两者有什么不同呢? 1.cElementTree速度上要比ElementTree快,比较cElemen ...

  6. 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  7. Ibatis XML 配置文件注释引起错误及解决方案

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp35 Ibatis XML 配置文件注释引起错误及解决方案 最近在使用Iba ...

  8. 编辑xml文件时不能自动提示问题的解决

    在编辑xml文件时,eclipse总是不能自动提示,在网上找了一些资料,大部分都是说关于xml editor配置的,下面也把这个方法罗列在下面,以供参考: 解决办法:在eclipse的菜单里,找到wi ...

  9. 项目配置 xml文件时 报错提示(The reference to entity "useSSL" must end with the ';' delimiter.)

    这次在配置xml文件时,出现错误提示( The reference to entity “useSSL” must end with the ‘;’ delimiter.) 报错行为 <prop ...

随机推荐

  1. scala case类

    case类 case class Person(name:String) case 类有如下特点: 1. 构造参数默认是 val 的. 2. case 类实例化对象的时候,不需要 new 关键字.因为 ...

  2. python判断任务是CPU密集型还是IO密集型

    目前已经知道,在需要并发执行任务的时候,需要使用多线程或者多进程;如果是IO密集型任务,使用多线程,如果是CPU密集型任务,使用多进程;但问题是,经常我们会遇到一种情况就是:需要被执行的任务既有IO操 ...

  3. Javascript概念

    什么是JavaScript? 1 以前的目的:验证表单输入的正确性. 2 现在的目的:多做一些页面的交互效果. 3 javascript是一个跨平台的脚本语言. 4 网景公司开发的,由布兰登·艾奇最先 ...

  4. c#批量更新list对象sql

    注意: 1.语句中"set "后有空格, 2.最后一个if一定有值,且接连的sql字段 无  逗号 3.parameterList.Clear(); /// <summary ...

  5. 解题8(FindLongestNumberStr)

    题目描述 样例输出 输出123058789,函数返回值9 输出54761,函数返回值5 接口说明 函数原型: unsignedint Continumax(char** pOutputstr,  ch ...

  6. mysql 定时备份任务

    备份方案: 本地备份并同步至远程服务器,保留30天数据 1. 本地数据库备份,备份数据库gold_ecooy,naiang#!/bin/bash#xliang#Created Time: 2018-1 ...

  7. PUDN用户名与密码

    Pudn 用户名与密码 boumang8171    que2538  温馨提示:1.  95%的用户第一次登录不成功,都是因为在复制粘贴帐号和密码时,把空格也复制粘贴上了.2. 如果连续3次帐号或密 ...

  8. 全国高校绿色计算大赛 预赛第一阶段(C++)第4关:计算日期

    挑战任务 我们吃的食物都有保质期,现在食品监督管理局想要制作一个能准确计算食品过期日期的小程序,需要请你来进行设计. 例如:A食品在2018年1月1日生产,保质期是20天,则它的过期日期在2018年1 ...

  9. K-邻近算法简单例子

    from numpy import * import operator import matplotlib.pyplot as plt def creatDataset(): group = arra ...

  10. JAVA jar 参数

    -client       to select the "client" VM    -server       to select the "server" ...