在 Android 应用程序中使用 Intern…

使用 JSON

XML 是 Android 上的一等公民,鉴于依赖于 XML 的 Web 服务的数量,这是个好事。很多服务还支持另一个流行格式 JSON。它通常比 XML 简洁一些,但也是人们可读的,使得它更易于使用,并且可以更轻松地将其用于调试使用它的应用程序。Android 包括一个 JSON 解析器。(您可以从 JSON.org 网站获得该解析器,只是要去除几个手机不需要的类)。 清单 9 显示了使用中的解析器:


清单 9. JSON 解析器实现

                          
private class StockJsonParser extends BaseStockParser{
    public StockJsonParser(){
        super("json");
    }
    @Override
    protected Stock[] doInBackground(String... symbols) {
        Stock[] stocks = new Stock[symbols.length];
        try{
            StringBuilder json = new StringBuilder();
            BufferedReader reader = 
                new BufferedReader(
                            new InputStreamReader(getData(symbols)));
            String line = reader.readLine();
            while (line != null){
                json.append(line);
                line = reader.readLine();
            }
            JSONObject jsonObj = new JSONObject(json.toString());
            JSONArray stockArray = jsonObj.getJSONArray("stocks");
            for (int i=0;i<stocks.length;i++){
                JSONObject object = 
                    stockArray.getJSONObject(i).getJSONObject("stock");
                stocks[i] = new Stock(object.getString("symbol"), 
                        object.getString("name"), 
                        object.getDouble("price"));
            }
        } catch (Exception e){
            Log.e("DayTrader", "Exception getting JSON data", e);
        }
        return stocks;
    }
}

 

 

可以看到在 Android 中使用 JSON 解析器是多么简单。您将来自服务器的流转换成传递给 JSON 解析器的字符串。您遍历对象图并创建 Stock 对象数组。如果使用过 XML DOM 解析,这看起来很类似,因为编程模型几乎一样。

像 DOM 一样,JSON 解析器可以用于内存密集型应用。在 清单 9 中,所有来自服务器的数据都表示为字符串,然后作为 JSONObject,最后作为 Stock 对象数组。换句话说,同一数据通过三种不同的方式表示。可以看到,对于大量数据而言,这可能是个问题。当然,一旦到达方法末尾,这三种数据表示方式中的两种都会落在范围之外,被垃圾回收器回收。但是,只是触发更频繁的垃圾回收可能会对用户体验带来负面影响,造成处理速度下降。如果内存效率和性能很重要,使用 protocol buffers 的解析器可能是个较好的选择。

使用 protocol buffers 处理二进制

Protocol buffers 是一个由 Google 开发的与语言无关的数据串行化格式,旨在比 XML 更快地通过网络传送数据。它是 Google 用于服务器对服务器调用的事实 标准。Google 将该格式及其用于 C++、Java 和 Python 编程语言的绑定工具以开源方式提供。

在 清单 3 和 清单 6 中看到 protocol buffers 是二进制格式。如您所料,这使得数据很简洁。如果在客户端和服务器端启用 gzip 压缩,在使用 XML 和 JSON 时通常也可以得到类似的消息大小,但是 protocol buffers 仍然有一些大小上的优势。它还是一种可以迅速解析的格式。最后,它提供了一个相当简单的 API。 清单 10 显示了一个示例解析器实现:


清单 10. Protocol buffers 解析器实现

                             
private class StockProtoBufParser extends BaseStockParser{
    public StockProtoBufParser(){
        super("protobuf");
    }

    @Override
    protected Stock[] doInBackground(String... symbols) {
        Stock[] stocks = new Stock[symbols.length];
        try{
            Stocks.Portfolio portfolio = 
                Stocks.Portfolio.parseFrom(getData(symbols));
            for (int i=0;i<symbols.length;i++){
                stocks[i] = Stock.fromQuote(portfolio.getQuote(i));
            }
        } catch (Exception e){
            Log.e("DayTrader", "Exception getting ProtocolBuffer data", e);
        }
        return stocks;
    }
}

 

 

如 清单 3 所示,您可以使用 protocol buffers 编译器生成的 helper 类。这与服务器使用的 helper 类相同。可以编译它一次,然后在服务器和客户端共享它。 这样,您可以更轻松地直接从服务器的流读取数据并将其转换成 Stock 对象数组。这种简单编程也具有非常出色的性能。现在看一下此性能与 XML 和 JSON 的比较。

性能比较

比较性能通常涉及某种微基准测试,此类基准测试很容易产生偏见或无意间得到不正确的结果。即使以公平方式设计微基准测试,很多随机因素也会对结果产生影响。尽管有这些问题,我还是要使用这样的微基准测试来比较 XML(大约 1300 ms)、JSON(大约 1150 ms)和 protocol buffers(大约 750 ms)。基准测试向服务器发送了一个关于 200 个股票的请求并测量了从发出请求到用于创建ListView 的 Adapter 的数据准备就绪所需的时间量。对每个数据格式在两个设备上进行 50 次这样的操作:一个 Motorola Droid 和一个 HTC Evo,两个都通过 3G 网络。 图 2 显示了结果:


图 2. 比较数据格式速度
柱状图比较了数据格式速度:XML、JSON 和 protocol buffers  
 

图 2 显示出,在此基准测试中 protocol buffers(大约 750 ms)比 XML (大约 1300 ms)几乎快两倍。很多因素影响着数据通过网络和被手持设备处理的性能。一个明显的因素是通过网络的数据量。二进制格式的 protocol buffers 比文本格式的 XML 和 JSON 在通过网络时小得多。然而,文本格式可以使用 gzip 进行有效地压缩,这是 Web 服务器和 Android 设备都支持的标准技术。 图 3显示了在打开和关闭 gzip 时通过网络的数据大小:


图 3. 不同格式的数据大小
比较不同格式数据大小的柱状图:XML 和 JSON(原始或压缩状态)与 protocol buffers 之比较  
 

图 3 应该增加了您对 XML 和 JSON 之类的文本内容的压缩效果的喜爱(更不用说 Web 格式、HTML、JavaScript 和 CSS 了)。protocol buffers 数据(大约 6KB)比原始 XML(大约 17.5KB)或 JSON(大约 13.5KB)数据小得多。但是一旦进行了压缩, JSON 和 XML(都是大约 3KB)实际上比 protocol buffers 小很多了。在本例中,它们都接近于 protocol-buffers 编码消息大小的一半了。

回到 图 2,速度的不同显然不能由通过网络的消息大小解释。protocol-buffers 消息比 XML 或 JSON 编码的消息大,但是通过使用 protocol buffers,您仍然能够削减半秒钟的用户等待时间。这是否意味着应该在 Android 应用程序中使用 protocol buffers 呢?这样的决定很少是固定的。如果要发送的数据量很小,则三种格式间的差异也不大。对于大量数据而言,protocol buffers 可能会有所不同。但是,像这样精心设计的基准测试无法替代对您自己的应用程序的测试。

结束语

本文介绍了如何使用 Internet 上流行的两种数据格式 XML 和 JSON 的方方面面。还讲到了第三种可能性,protocol buffers。像软件工程中的其他内容一样,选择技术主要就是权衡利弊。当您为一个局限的环境(比如 Android)开发时,这些决定的结果往往被放大了。我希望您现在拥有的关于这些后果的额外知识能够帮助您创建出色的 Android 应用程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值