分类: 嵌入式

(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. 瑞游天翼客户端win7,win8,win10

    以管理员身份运行即可, 链接: http://pan.baidu.com/s/1kTw7VH9 密码: vttq

  2. OLEDB和ODBC的区别

    ODBC(开放数据库互连):是Microsoft引进的一种早期数据库接口技术.它实际上是ADO的前身.早期的数据库连接是非常困难的. 每个数据库的格式都不一样,开发者得对他们所开发的每种数据库的底层A ...

  3. c语言中gets ,getschar 和fgets 的用法及三者之间的差别

    gets——从标准输入接收一串字符,遇到'\n'时结束,但不接收'\n',把 '\n'留存输入缓冲区:把接收的一串字符存储在形式参数指针指向的空间,并在最后自动添加一个'\0'.getchar——从标 ...

  4. css3 media媒体查询器用法总结 兼容ie8以下的方法

    总结一下响应式设计的核心CSS技术Media(媒体查询器)的用法. http://www.360doc.com/content/14/0704/06/10734150_391862769.shtml ...

  5. Idea 设置根目录

    1.在根目录下新建一个目录yx360-war-ctm-tea,在该目录下新建一个build.gradle文件,输入: apply plugin: 'war' 来引入war插件,war插件会在项目的目录 ...

  6. 这种方法在受到.NET版本和访问注册表权限时,是最佳解决方案,虽然代码看起来很多,不过下面的类直接拿走用就可以了。

    public class FileContentType  {      private static IDictionary<string, string> _mappings = ne ...

  7. android--屏幕旋转方法总结

    在介绍之前,我们需要先了解默认情况下android屏幕旋转的机制: 默认情况下,当用户手机的重力感应器打开后,旋转屏幕方向,会导致当前activity发生onDestroy-> onCreate ...

  8. sql server中单引号拼接字符串(书写错误会出现错误"浮点值 XXXX 超出了计算机表示范围(8 个字节)。“XX”附近有语法错误。")

    " ' "(单引号)的运用:在sql server中,两个" ' "(单引号)在拼接字符串的情况下运用,就是表示拼接上了一个" ' "单引号 ...

  9. 巧妙使用Contains()方法查找一个数是否在某堆数中

    问题:要判断用户输入的一个数,或者是程序里方法的一个参数的值,或者是一个变量的值是否在某堆数中. 简洁写法:把这堆数放在list中,使用list的Contains()方法检查list是否包含这个数,取 ...

  10. 在windows系统用odbc连接

    当连接的数据出现失败时,出现数据库别名仍然存在,但还是要用这个别名重新建立连接 在windows客户端,用输入db2cmd输入c:\Users\yexuxia>db2 list db direc ...