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

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

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

看一下存在问题的版本:

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

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

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

  1. 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. macbook pro。已经连接上wifi,但是,不能上网的问题

    有天,macbook pro关机后,再打开就上不了网了,后面网上看了,说是安装了 lantern出问题,我一想,有次关机lantern是被我强制关掉的.所以再次打开lantern就可以 上网了,然后正 ...

  2. input 文本框,对中文长度校验

    在项目中,经常会遇到,对文本框进行校验. eg.  要求姓名长度为20,中文为10,只能输入中英文. <input   maxlength="20" type="t ...

  3. centos静态绑定IP地址

    Centos7 /etc/sysconfig/network-scripts/ifcfg-ens33

  4. pngencoder图像转换jar

    PngEncoder - convert a Java Image to PNGPngEncoderB - convert a Java BufferedImage to PNG Written by ...

  5. Mysql 单表操作、增删查改(基础4)

    新建一个表,往里面插入数据. #新建一个表 mysql> create table test( -> id int, -> name varchar(20) -> );Quer ...

  6. PHPActiveRecord validates

    validates_presence_of #检测是不是为空 为空的话可以抛出异常 *Model类: static $validates_presence_of = array( array('tit ...

  7. IDEA中配置JUnit单元测试

    参考安装教程:https://www.jianshu.com/p/c37753b6dbd6 如果想用junit4的话,需要在pom.xml中配置. 需要安装JUnitGenerator V2.0插件, ...

  8. 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确

    安装好后,登录后台提示 无法连接mysql,请检查mysql是否已启动及用户密码是否设置正确 检查mysql是否启动netstat -lnpt是否有3306端口? 一 有A 检查/www/wdlinu ...

  9. linux下安装kafka

    安装条件: 确保zookeeper已经安装成功.zookeeper安装过程见:https://www.cnblogs.com/expiator/p/9853378.html 1.下载kafka 进入A ...

  10. Local Storage

    HTML代码: <ul id="edit" contenteditable="true"> <li>修改我吧,然后刷新页面看看,^_^& ...