Android] Android XML解析学习——方式比较

[Android] Android XML解析学习——方式比较 (ZT)

分类: 嵌入式

(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文件中添加权限:

view plain

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

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

view plain

  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文件的内容为:

view plain

  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解析方式的解析过程,并且分别记录解析前和解析后的系统时间来计算解析所花费的时间,

view plain

  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,我们以后接着学习。

时间: 2024-10-13 04:16:12

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

Android实现XML解析技术

http://www.cnblogs.com/hanyonglu/archive/2012/02/28/2370675.html http://weizhulin.blog.51cto.com/1556324/311678 Android实现XML解析技术

由XML解析学习工厂模式

代码段1: startupData = new StartupData(); /* 设定自定义的MyHandler给XMLReader */ StartupXMLHandler startupDataXMLHandler = new StartupXMLHandler(); startupDataXMLHandler.setData(startupData); /* 产生SAXParser对象 */            SAXParserFactory spf = SAXParserFacto

Android 之xml解析

HTTP网络传输中的数据组织方式有三种方式:1.HTML方式2.XML方式 3.JSON方式 XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言) XML是Internet环境中跨平台的,依赖于内容技术,是当前处理结构化文档信息的有力工具,可扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据. xml文件的节点的种类,一种是ElementNode,一种是TextNode.像<persons>.<person>这种节点就属于Element

Android中XML解析-PULL解析

前面写了两篇XML解析的Dom和SAX方式,Dom比较符合思维方式,SAX事件驱动注重效率,除了这两种方式以外也可以使用Android内置的Pull解析器解析XML文件. Pull解析器的运行方式与 SAX 解析器相似,也是事件触发的.Pull解析方式让应用程序完全控制文档该怎么样被解析,比如开始和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.通过Parser.getEventType()方法来取得事件的代码值,解析是在开始时就完成了大部分处理.事件将作为数值代码

Android中XML解析-Dom解析

Android中需要解析服务器端传过来的数据,由于XML是与平台无关的特性,被广泛运用于数据通信中,有的时候需要解析xml数据,格式有三种方式,分别是DOM.SAX以及PULL三种方式,本文就简单以Dom解析为例,解析XML, DOM方式解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据的,但是这样一来,如果xml文件很大,手机CPU处理能力比PC差,因此在处理效率方面就相对差了,使用Dom解析就不是太合适了. 基础维护 首先下assets目录下新建一个Bo

Android 简易XML解析

首先创建在Android工程中创建一个Assets文件夹 app/src/main/assets 在这里添加一个名为 data.xml的文件,然后编辑这个文件,加入如下XML格式内容 <?xml version="1.0" encoding="utf-8"?> <apps> <app> <id>1</id> <name>Google Maps</name> <version&g

Android中XML解析

package com.example.thebroadproject; public class Book { private int id; private String name; private float price; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setN

android之XML解析

所谓SAX,就是SAX simple API for XML,是一个解析XML文件的简单API. SAX解析XML的工作原理,是对文档进行顺序扫描,当扫描到文档开始与结束,元素开始与结束,触发相应的响应函数.是一种事件驱动型的解析方式.它可以在解析文档的任意时刻停止解析. 通过该图我们可以大概了解解析的过程. private void parse(String xmlString,List<Mp3Info> infos){ // SAXParserFactory 是一个使用工厂模式的类 SAX

XML解析---DOM方式

XML解析方法分为两种:DOM方式和SAX方式 DOM:Document Object Model,文档对象模型.这种方式是W3C推荐处理XML的一种方式 SAX:Simple API for XML.该方式不是官方标准,属于开源社区XML-DEV XML解析开发包 JAXP:SUN公司推出的解析标准实现 Dom4J:开源组织推出的解析开发包 JDOM:同上 JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成 org.w3