请注意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应用程序的构成
  2. Android 混合了 JSON 的 Android 应用程序
  3. 第一个Android程序--Hello Android
  4. 常用Android应用程序中的Intent动作
  5. Android 再按一次退出程序三种办法

随机推荐

  1. Go语言实现之基于websocket浏览器通知功
  2. 关于用Go语言编程的利与弊
  3. 如何使用go优雅地撰写单元测试
  4. golang用什么开发工具?
  5. 详解 Go 语言中的方法
  6. 教你导入golang.org的包
  7. golang是多线程模式吗?
  8. Go如何使用websocket实现弹幕功能
  9. golang是单进程的吗?
  10. golang如何释放map内存?