清单 7 中的基类扩展了 android.os.AsyncTask。这是一个常用的用于异步操作的类。它抽象出线程和处理程序的创建,用于请求主 UI
线程。它是基于其输入和输出数据类型参数化的。对于所有解析器而言,输入总是一样的:股票代码字符串。 输出也是一样的:Stock 对象数组。基类获取
format,这是一个指定了要使用的数据格式的字符串。然后提供一个方法,发出适当的 HTTP 请求并返回一个流响应。最后,它覆盖 AsyncTask 的
onPostExecute() 方法并使用从解析器返回的数据为 Activity 的 ListView 创建一个 Adapter。
现在看到三个解析器的功能是通用的。我将为您展示更具体的解析代码,从 XML 解析器开始。
回页首
用 SAX 解析 XML
Android SDK 提供了几种使用 XML 的方式,包括标准 DOM 和 SAX。 对于一些对内存密集型情况,可以使用 SDK 的
pull-parser。大部分时候,SAX 是最快的方式。Android 包括一些便捷的 API 使得使用 SAX 更轻松。清单 8 显示了 Day
Trader 应用程序的 XML 解析器:
清单 8. XML 解析器实现
private class StockXmlParser extends BaseStockParser{ public StockXmlParser(){ super("xml"); }
@Override protected Stock[] doInBackground(String... symbols) { ArrayList<Stock> stocks = new ArrayList<Stock>(symbols.length); try{ ContentHandler handler = newHandler(stocks); Xml.parse(getData(symbols), Xml.Encoding.UTF_8, handler); } catch (Exception e){ Log.e("DayTrader", "Exception getting XML data", e); } Stock[] array = new Stock[symbols.length]; return stocks.toArray(array); }
private ContentHandler newHandler(final ArrayList<Stock> stocks){ RootElement root = new RootElement("stocks"); Element stock = root.getChild("stock"); final Stock currentStock = new Stock(); stock.setEndElementListener( new EndElementListener(){ public void end() { stocks.add((Stock) currentStock.clone()); } } ); stock.getChild("name").setEndTextElementListener( new EndTextElementListener(){ public void end(String body) { currentStock.setName(body); } } ); stock.getChild("symbol").setEndTextElementListener( new EndTextElementListener(){ public void end(String body) { currentStock.setSymbol(body); } } ); stock.getChild("price").setEndTextElementListener( new EndTextElementListener(){ public void end(String body) { currentStock.setPrice(Double.parseDouble(body)); } } ); return root.getContentHandler(); } }
|