请注意Android中的 XmlPullParser.nextText()

使用XmlPullParser在Android上来解析XML文件是高效可维护的。由于历史原因,Android系统上有两种实现:

  • KXmlParser, 通过XmlPullParserFactory.newPullParser()函数获取
  • ExpatPullParser, 通过Xml.newPullParser()函数获取
Xml.newPullParser()的实现有个bug,当调用函数nextText() 后并不一定像文档描述的那样总是前进到END_TAG。一些程序可能使用再次调用next() 或者 nextTag()函数来解决这个问题。 帮助
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public void parseXml(Reader reader) throws XmlPullParserException, IOException { XmlPullParser parser = Xml.newPullParser(); parser.setInput(reader); parser.nextTag(); parser.require(XmlPullParser.START_TAG, null , "menu" ); while (parser.nextTag() == XmlPullParser.START_TAG) { parser.require(XmlPullParser.START_TAG, null , "item" ); String itemText = parser.nextText(); parser.nextTag(); // this call shouldn’t be necessary! parser.require(XmlPullParser.END_TAG, null , "item" ); System.out.println( "menu option: " + itemText); } parser.require(XmlPullParser.END_TAG, null , "menu" ); } public static void main(String[] args) throws Exception { new Menu().parseXml( new StringReader( "<?xml version='1.0'?>" + "<menu>" + " <item>Waffles</item>" + " <item>Coffee</item>" + "</menu>" )); }

在冰激凌三明治(Android 4.0)版本中,Android团队修改了Xml.newPullParser()函数的实现,返回KxmlParser 并且删除了ExpatPullParser 类。这样修复了nextTag() bug。不幸的是那些按照上面的代码修改该bug的程序在4.0系统上运行将会崩溃。

帮助
1 2 3 4 org.xmlpull.v1.XmlPullParserException: expected: END_TAG { null }item (position:START_TAG <item> @1 : 37 in java.io.StringReader @40442fa8 ) at org.kxml2.io.KXmlParser.require(KXmlParser.java: 2046 ) at com.publicobject.waffles.Menu.parseXml(Menu.java: 25 ) at com.publicobject.waffles.Menu.main(Menu.java: 32 )

可以按照如下的方式来修复该问题,调用函数nextText()后只有当前位置不是END_TAG 的时候才调用nextTag()。

帮助
1 2 3 4 5 6 7 8 9 while (parser.nextTag() == XmlPullParser.START_TAG) { parser.require(XmlPullParser.START_TAG, null , "item" ); String itemText = parser.nextText(); if (parser.getEventType() != XmlPullParser.END_TAG) { parser.nextTag(); } parser.require(XmlPullParser.END_TAG, null , "item" ); System.out.println( "menu option: " + itemText); }

上面的代码在所有的Android版本上都能正常运行。如果您的程序使用了nextText()函数,请使用下面的助手函数来替代所有的nextText()函数调用:

帮助
1 2 3 4 5 6 7 8 private String safeNextText(XmlPullParser parser) throws XmlPullParserException, IOException { String result = parser.nextText(); if (parser.getEventType() != XmlPullParser.END_TAG) { parser.nextTag(); } return result; }

现在只使用一个 XmlPullParser 实现,可以让维护系统更简单并且可以让Android开发团队集中精力在提高系统性能上面。



更多相关文章

  1. Android(安卓)CountDownTimer实现定时器和倒计时效果
  2. android的九宫格式实现
  3. 设置Activity全屏
  4. android 动画之Scroller
  5. Android实现录音功能及播放语音功能
  6. Android(安卓)应用语言设置的实现
  7. 浅谈Java中Collections.sort对List排序的两种方法
  8. 箭头函数的基础使用
  9. Python技巧匿名函数、回调函数和高阶函数

随机推荐

  1. 面试题总结(2018.7.26开始,持续更新中)
  2. AndroidStudio使用笔记
  3. Android,App 常用图标尺寸规范
  4. Android(安卓)Material Design :LinearLay
  5. Android查看数据库工具sqlitemanager
  6. Menu
  7. MyEclipse本地搭建Android环境
  8. android混淆
  9. android 实现悬架控制
  10. android中ContactsContract获取联系人的