分类: 嵌入式

(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. iOS tableView的系统分割线定格设置以及分割线自定制

    一.关于分割线的位置. 分割线的位置就是指分割线相对于tableViewCell.如果我们要根据要求调节其位置,那么在iOS7.0版本以后,提供了一个方法如下: if ([self.tableView ...

  2. PhpMyAdmin管理SQLSERVER的问题

    由于项目需要对MSSQL做管理(多个版本的) 之前有个websqladmin的一个开源的项目,但是感觉功能太弱了,而且,采用的SQLDMO的方式,有点过时了. 所以考虑对其升级,方案大概有几种: 1. ...

  3. SMO 的环境

    Microsoft SQL Server System CLR Types - http://go.microsoft.com/fwlink/?LinkId=123721&clcid=0x40 ...

  4. 《TCP/IP详解》读书笔记

    本书以UNIX为背景,紧贴实际介绍了数据链层.网络层.运输层   一.整体概念   1.各层协议的关系,只讨论四层 各层常见的协议:   网络层协议:IP协议.ICMP协议.ARP协议.RARP协议. ...

  5. 批处理 取得当前路径 %CD%

    在DOS的批处理中,有时候需要知道当前的路径.在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0. 这两个变量的用法和代表的内容一般是不同的. 1. %cd% 可以用在批 ...

  6. DB9_公头_母头_串口引脚定义及RS-232串口线制作方法

    RS-232连接线制作方法 材料及工具 一根双绞线(8芯).一个标准RJ45头.一个DB9孔型插头.一把RJ45专用工具.一个电烙铁及若干焊锡. 引脚定义 按以下管脚定义制作RJ45端头:I表示网络视 ...

  7. LeetCode OJ 202. Happy Number

    Write an algorithm to determine if a number is "happy". A happy number is a number defined ...

  8. Entity Framework中对存储过程的返回值的处理

    很早就开始注意到EF了,但一直没有机会用,换了工作后,第一个项目就使用EF6进行开发. 项目不是很大,EF完全可以胜任. 但是开发过程中,难免还是会遇到一些复杂的运算,需要频繁访问数据库. 此时,想到 ...

  9. 特殊字符 js处理

    2.特殊字符传递过程中的处理 (1)js页面的处理 var url= "#@+&这些带有特殊字符"; url=encodeURI(encodeURI(url));//转码两 ...

  10. think in uml-关系

    1.关联关系association 在一段时间内将多个类的实例连接在一起 某个对象在一段时间内一直"知道"另一个对象的存在 2.依赖关系dependency 一个对象的修改会导致另 ...