分类: 嵌入式

(From:http://blog.csdn.net/ichliebephone/article/details/5981913)

一.基础知识

经过这段时间的学习,我们已经了解了Android平台上用于解析XML的三种方式:SAX、DOM和Pull。并且在学习的过程中也介绍了这三种方式各自的特点及适合的使用场合,简单的来说,DOM方式最直观和容易理解,但是只适合XML文档较小的时候使用,而SAX方式更适合在Android系统中使用,因为相比DOM占用内存少,适合处理比较大的XML文档,最后的Pull方式使用场合和SAX类似,但是更适合需要提前结束XML文档解析的场合。

在这部分的学习中,我们将对以上三种方式解析XML的性能进行一下简单的比较,通过记录比较他们读取相同XML文档的时间来更好的理解他们的性能,从而使你在不同的场合更好的选择使用那一种XML的解析方式。

下面我们就用上面介绍的几种方式来实现解析XML形式的USGS地震数据的Demo例子以作比较。

二.实例开发

我们要完成的效果图如下图1所示:

图1 各种方式解析花费的时间比较

我们分别使用Java SAX,Android SAX,DOM和Pull方式解析相同的XML地震数据,并记录他们完成解析所花费的时间,结果如上图所示。

新建一个Android工程AndroidXMLDemoCompare。

添加进之前Demo工程AndroidXMLDemoSax中的EarthquakeEntry.java和SaxEarthquakeHandler.java文件,工程AndroidXMLDemoSaxII中的AndroidSaxEarthquakeHandler.java文件,工程AndroidXMLDemoDom中的DomEarthquakeHandler.java文件,和工程AndroidXMLDemoPull中的PullEarthquakeHandler.java文件。

如果需要从本地读取xml数据的话,同时在assets文件夹下添加保存为xml格式了的USGS地震数据USGS_Earthquake_1M2_5.xml和USGS_Earthquake_7M2_5.xml,如果需要联网读取的话,在manifest.xml文件中添加权限:

  1. <uses-permission android:name="android.permission.INTERNET" />

并修改res/layout下的main.xml为:

  1. xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <Button
  8. android:id="@+id/javaSaxBtn"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:text="Java SAX Parse"
  12. >
  13. Button>
  14. <Button
  15. android:id="@+id/androidSaxBtn"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content"
  18. android:text="Android SAX Parse"
  19. >
  20. Button>
  21. <Button
  22. android:id="@+id/domBtn"
  23. android:layout_width="fill_parent"
  24. android:layout_height="wrap_content"
  25. android:text="DOM Parse"
  26. >
  27. Button>
  28. <Button
  29. android:id="@+id/pullBtn"
  30. android:layout_width="fill_parent"
  31. android:layout_height="wrap_content"
  32. android:text="PULL Parse"
  33. >
  34. Button>
  35. <TextView
  36. android:id="@+id/javaSaxText"
  37. android:layout_width="fill_parent"
  38. android:layout_height="wrap_content"
  39. android:text="Java SAX Parse Time:">
  40. TextView>
  41. <TextView
  42. android:id="@+id/androidSaxText"
  43. android:layout_width="fill_parent"
  44. android:layout_height="wrap_content"
  45. android:text="Android SAX Parse Time:">
  46. TextView>
  47. <TextView
  48. android:id="@+id/domText"
  49. android:layout_width="fill_parent"
  50. android:layout_height="wrap_content"
  51. android:text="DOM Parse Time:">
  52. TextView>
  53. <TextView
  54. android:id="@+id/pullText"
  55. android:layout_width="fill_parent"
  56. android:layout_height="wrap_content"
  57. android:text="PULL Parse Time:">
  58. TextView>
  59. LinearLayout>

主要定义了4个分别启动Java SAX、Android SAX、DOM和Pull方式解析的按钮Button,和4个显示解析所花费时间的TextView。

接着修改AndroidXMLDemoCompare.java文件的内容为:

  1. public class AndroidXMLDemoCompare extends Activity {
  2. /** Called when the activity is first created. */
  3. //定义变量
  4. Button javaSaxBtn, androidSaxBtn, domBtn, pullBtn;
  5. TextView javaSaxText, androidSaxText, domText, pullText;
  6. ArrayList earthquakeEntryList;
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.main);
  11. //测试各个xml解析方法的速度
  12. javaSaxBtn = (Button)findViewById(R.id.javaSaxBtn);
  13. androidSaxBtn = (Button)findViewById(R.id.androidSaxBtn);
  14. domBtn = (Button)findViewById(R.id.domBtn);
  15. pullBtn = (Button)findViewById(R.id.pullBtn);
  16. javaSaxText = (TextView)findViewById(R.id.javaSaxText);
  17. androidSaxText = (TextView)findViewById(R.id.androidSaxText);
  18. domText = (TextView)findViewById(R.id.domText);
  19. pullText = (TextView)findViewById(R.id.pullText);
  20. javaSaxBtn.setOnClickListener(new OnClickListener() {
  21. @Override
  22. public void onClick(View v) {
  23. // TODO Auto-generated method stub
  24. javaSaxBtn.setEnabled(false);
  25. androidSaxBtn.setEnabled(false);
  26. domBtn.setEnabled(false);
  27. pullBtn.setEnabled(false);
  28. //获取地震数据流
  29. InputStream earthquakeStream = readEarthquakeDataFromFile();
  30. String saxTime = "Java SAX Parse Time: 正在解析,请稍后...";
  31. javaSaxText.setText(saxTime);
  32. long beforeTime = System.currentTimeMillis();
  33. //Java Sax方式进行xml解析
  34. SAXParserFactory factory = SAXParserFactory.newInstance();
  35. try {
  36. SAXParser parser = factory.newSAXParser();
  37. SaxEarthquakeHandler saxHandler = new SaxEarthquakeHandler();
  38. parser.parse(earthquakeStream, saxHandler);
  39. //获取解析后的列表数据
  40. earthquakeEntryList = saxHandler.getEarthquakeEntryList();
  41. } catch (Exception e) {
  42. // TODO Auto-generated catch block
  43. e.printStackTrace();
  44. }
  45. //解析完毕
  46. long afterTime = System.currentTimeMillis();
  47. long parseTime = (afterTime - beforeTime);
  48. saxTime = "Java SAX Parse Time: " + String.valueOf(parseTime) + "毫秒";
  49. javaSaxText.setText(saxTime);
  50. javaSaxBtn.setEnabled(true);
  51. androidSaxBtn.setEnabled(true);
  52. domBtn.setEnabled(true);
  53. pullBtn.setEnabled(true);
  54. }
  55. });
  56. androidSaxBtn.setOnClickListener(new OnClickListener() {
  57. @Override
  58. public void onClick(View v) {
  59. // TODO Auto-generated method stub
  60. javaSaxBtn.setEnabled(false);
  61. androidSaxBtn.setEnabled(false);
  62. domBtn.setEnabled(false);
  63. pullBtn.setEnabled(false);
  64. //获取地震数据流
  65. InputStream earthquakeStream = readEarthquakeDataFromFile();
  66. String saxTime = "Android SAX Parse Time: 正在解析,请稍后...";
  67. androidSaxText.setText(saxTime);
  68. long beforeTime = System.currentTimeMillis();
  69. //Android Sax方式进行解析
  70. AndroidSaxEarthquakeHandler androidSaxHandler = new AndroidSaxEarthquakeHandler();
  71. earthquakeEntryList = androidSaxHandler.parse(earthquakeStream);
  72. //解析完毕
  73. long afterTime = System.currentTimeMillis();
  74. long parseTime = (afterTime - beforeTime);
  75. saxTime = "Android SAX Parse Time: " + String.valueOf(parseTime) + "毫秒";
  76. androidSaxText.setText(saxTime);
  77. javaSaxBtn.setEnabled(true);
  78. androidSaxBtn.setEnabled(true);
  79. domBtn.setEnabled(true);
  80. pullBtn.setEnabled(true);
  81. }
  82. });
  83. domBtn.setOnClickListener(new OnClickListener() {
  84. @Override
  85. public void onClick(View v) {
  86. // TODO Auto-generated method stub
  87. javaSaxBtn.setEnabled(false);
  88. androidSaxBtn.setEnabled(false);
  89. domBtn.setEnabled(false);
  90. pullBtn.setEnabled(false);
  91. //获取地震数据流
  92. InputStream earthquakeStream = readEarthquakeDataFromFile();
  93. String domTime = "DOM Parse Time: 正在解析,请稍后...";
  94. domText.setText(domTime);
  95. long beforeTime = System.currentTimeMillis();
  96. //Dom方式进行xml解析
  97. DomEarthquakeHandler domHandler = new DomEarthquakeHandler();
  98. earthquakeEntryList = domHandler.parse(earthquakeStream);
  99. //解析完毕
  100. long afterTime = System.currentTimeMillis();
  101. long parseTime = (afterTime - beforeTime);
  102. domTime = "DOM Parse Time: " + String.valueOf(parseTime) + "毫秒";
  103. domText.setText(domTime);
  104. javaSaxBtn.setEnabled(true);
  105. androidSaxBtn.setEnabled(true);
  106. domBtn.setEnabled(true);
  107. pullBtn.setEnabled(true);
  108. }
  109. });
  110. pullBtn.setOnClickListener(new OnClickListener() {
  111. @Override
  112. public void onClick(View v) {
  113. // TODO Auto-generated method stub
  114. javaSaxBtn.setEnabled(false);
  115. androidSaxBtn.setEnabled(false);
  116. domBtn.setEnabled(false);
  117. pullBtn.setEnabled(false);
  118. //获取地震数据流
  119. InputStream earthquakeStream = readEarthquakeDataFromFile();
  120. String pullTime = "PULL Parse Time: 正在解析,请稍后...";
  121. pullText.setText(pullTime);
  122. long beforeTime = System.currentTimeMillis();
  123. //Pull方式进行xml解析
  124. PullEarthquakeHandler pullHandler = new PullEarthquakeHandler();
  125. earthquakeEntryList = pullHandler.parse(earthquakeStream);
  126. //解析完毕
  127. long afterTime = System.currentTimeMillis();
  128. long parseTime = (afterTime - beforeTime);
  129. pullTime = "PULL Parse Time: " + String.valueOf(parseTime) + "毫秒";
  130. pullText.setText(pullTime);
  131. javaSaxBtn.setEnabled(true);
  132. androidSaxBtn.setEnabled(true);
  133. domBtn.setEnabled(true);
  134. pullBtn.setEnabled(true);
  135. }
  136. });
  137. }
  138. private InputStream readEarthquakeDataFromFile()
  139. {
  140. //从本地获取地震数据
  141. InputStream inStream = null;
  142. try {
  143. //1天内2.5级以上的地震数据,约20来条地震信息
  144. //          inStream = this.getAssets().open("USGS_Earthquake_1M2_5.xml");
  145. //7天内2.5级以上的地震数据,约200来条地震信息
  146. inStream = this.getAssets().open("USGS_Earthquake_7M2_5.xml");
  147. } catch (IOException e) {
  148. // TODO Auto-generated catch block
  149. e.printStackTrace();
  150. }
  151. return inStream;
  152. }
  153. private InputStream readEarthquakeDataFromInternet()
  154. {
  155. //从网络上获取实时地震数据
  156. URL infoUrl = null;
  157. InputStream inStream = null;
  158. try {
  159. //1天内2.5级以上的地震数据,约20来条地震信息
  160. infoUrl = new URL("http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml");
  161. //7天内2.5级以上的地震数据,约200来条地震信息
  162. //          infoUrl = new URL("http://earthquake.usgs.gov/earthquakes/catalogs/7day-M2.5.xml");
  163. URLConnection connection = infoUrl.openConnection();
  164. HttpURLConnection httpConnection = (HttpURLConnection)connection;
  165. int responseCode = httpConnection.getResponseCode();
  166. if(responseCode == HttpURLConnection.HTTP_OK)
  167. {
  168. inStream = httpConnection.getInputStream();
  169. }
  170. } catch (MalformedURLException e) {
  171. // TODO Auto-generated catch block
  172. e.printStackTrace();
  173. } catch (IOException e) {
  174. // TODO Auto-generated catch block
  175. e.printStackTrace();
  176. }
  177. return inStream;
  178. }
  179. }

首先也是定义各个Button和TextView控件,接着为各个Button注册单击事件处理器,在单击事件处理的回调函数中,主要就是运行对应XML解析方式的解析过程,并且分别记录解析前和解析后的系统时间来计算解析所花费的时间,

  1. long beforeTime = System.currentTimeMillis();
  2. //Android Sax方式进行解析
  3. AndroidSaxEarthquakeHandler androidSaxHandler = new AndroidSaxEarthquakeHandler();
  4. earthquakeEntryList = androidSaxHandler.parse(earthquakeStream);
  5. //解析完毕
  6. long afterTime = System.currentTimeMillis();
  7. long parseTime = (afterTime - beforeTime);

完成了,可以保存运行看下效果。

图2 解析时间比较

左图是解析1天内2.5级以上的地震数据,约20来条地震信息时各个解析方式所花费的时间,右图是解析7天内2.5级以上的地震数据,约180来条地震信息时各个解析方式所花费的时间。从上图我们可以看到Java SAX、Android SAX和Pull方式花费的时间基本差不多,因为他们都是基于事件处理的方式,并且Java SAX和Android SAX底层调用的都是相同的org.xml.sax包中XMLReader解析器。而DOM方式相对来说所花费的时间就会长点,在地震数据条数较少和较多时都比较长。因此不管是从内存的消耗角度或者解析使用的时间角度来考虑,在Android平台上的应用程序中都不太推荐使用DOM方式来解析XML数据。但是Java SAX、Android SAX和Pull就看你喜欢使用哪个和你具体的使用场合了,性能上他们基本相同。

三.总结

在这部分内容中我们学习了各个解析方式的性能比较,即解析同一个XML文档时所花费时间的比较,并且从结果可以看出DOM方式的性能相对来说差点,而Java SAX、Android SAX和Pull方式的性能基本相同。

这样我们就比较全面的学习了Android平台上对XML文档进行解析的各种方式,但目前我们只是使用现成的XML文档来解析,实际上在使用过程中我们可能还会需要构造XML文档,比如可能会有需要向服务器发送XML,或者把一份数据以XML的形式保存在本地,这块内容就是写XML,我们以后接着学习。

Android] Android XML解析学习——方式比较的更多相关文章

  1. Android实现XML解析技术

    转载:Android实现XML解析技术 本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为 ...

  2. Android中XML解析,保存的三种方法

    简单介绍 在Android开发中,关于XML解析有三种方式,各自是: SAX 基于事件的解析器.解析速度快.占用内存少.非常适合在Android移动设备中使用. DOM 在内存中以树形结构存放,因此检 ...

  3. Android项目--XML解析

    对于xml文件,一般有两种解析方式: -----pull解析-------- -----Sax解析------- 如果xml文件是本地文件,那么就好说了 AssetManager assetManag ...

  4. Android 简易XML解析

    首先创建在Android工程中创建一个Assets文件夹 app/src/main/assets 在这里添加一个名为 data.xml的文件,然后编辑这个文件,加入如下XML格式内容 <?xml ...

  5. Android中XML解析

    package com.example.thebroadproject; public class Book { private int id; private String name; privat ...

  6. Android 之xml解析

    HTTP网络传输中的数据组织方式有三种方式:1.HTML方式2.XML方式 3.JSON方式 XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言) XML是Internet环境 ...

  7. Android,XML解析

    XML解析三种方式 DOM 通用性强,它会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树.检索所需的数据: 简单直观,但需要将文档读取到内存,并不太适合移动设备: SAX ...

  8. Android中XML解析-Dom解析

    Android中需要解析服务器端传过来的数据,由于XML是与平台无关的特性,被广泛运用于数据通信中,有的时候需要解析xml数据,格式有三种方式,分别是DOM.SAX以及PULL三种方式,本文就简单以D ...

  9. Android中XML解析-SAX解析

    昨天由于时间比较匆忙只写了Android中的XML解析的Dom方式,这种方式比较方便,很容易理解,最大的不足就是内容多的时候,会消耗内存.SAX(Simple API for XML)是一个解析速度快 ...

随机推荐

  1. php错误记录

    1.模板不存在ThinkPHP\Library\Think\View.class.php LINE: 110 是因为IndexController的Index函数,而View中没有对应的Index文件 ...

  2. 《C++ Primer》之面向对象编程(三)

    继承情况下的类作用域 在继承情况下,派生类的作用域嵌套在基类作用域中.如果不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义.正是这种类作用域的层次嵌套使我们能够直接访问基类的成员,就 ...

  3. VS2008中Run-Time Check Failure #2 - Stack around the variable 'xxx' was corrupted 错误解决方法

    问题 : 在用VS2008写一段代码,算法都没有问题,但是调试的时候发现出了main之后就报 Stack around the variable 'xxx' was corrupted 的错误,后来发 ...

  4. vbs和qtp一些脚本

    ********************************************************************************************** 用vbs调 ...

  5. Kubernetes 1.5.1 部署

    > kubernetes 1.5.0 , 配置文档 # 1 初始化环境 ## 1.1 环境: | 节 点  |      I P      ||--------|-------------||n ...

  6. form表单中的带有name的标签直接转JSON

    1. 将如下内容引入页面:比如说新建一个 a.js,然后在页面中引入a.js//将form表单序列化成json格式 $.fn.serializeObject = function () { var o ...

  7. mysql 数据表

    CREATE DATABASE IF NOT EXISTS  `shop`;USE `shop`; drop table if exists lidepeng; create table lidepe ...

  8. java IO类图

  9. mvc Controller类介绍

    1.Controller类 i.Controller必须为公开类: ii.必须以Controller结尾: iii.继承Controller基类或实现IController接口的类: iv.类中必须包 ...

  10. Canvas 数学、物理、动画学习笔记一

    Canvas 第五章 数学.物理和运动学习笔记让人映像深刻的运动,需要我们不只是简单的知道如何移动对象,还需要知道怎么按用户期望看到的方式去移动它们.这些需要基于数学知识的基本算法和物理学作用.基于点 ...