在 Android 上使用 XML 和 JSON,第 1 部分: 在 Android 应用程序上研究 JSON 和 XML 益处
移动设备和平台吹嘘每个新版本都有更多特性和功能,并且仅仅数月重要通告就从主流移动设备提供商中分离出来了。标题多数是关于 UI 特性(例如先进的多点触摸功能和 Adobe? Flash? 技术)以及硬件提升(例如,处理器速度和存储容量)。但是至关重要的仍然是 “内容为王”。内容 — 或者,一般来说,是数据 — 在应用程序、服务器、移动设备和用户之间不停地被交换。智能手机,如 Apple 的 iPhone 和 Google 的 Android 只是标价过高且表现不佳的移动电话,而且也不能很好的工作 。
常用缩略语考虑到社会网络非比寻常的成功,例如:Facebook、LinkedIn 和 Twitter。单从特征和功能的角度来说,这些平台很大程度上都是单调的,之所以流行是因为会员和网站访问者可以从其公布的内容获益。而且,其内容逐渐可以通过移动设备访问。
这篇文章主要说明 Android 平台上 XML 和 JSON 数据交换格式的使用。对于一个 Twitter 帐户,示例应用程序数据源是一个状态更新 feed。Feed 数据可以以 XML 和 JSON 格式从 Twitter 上获取。正如您所看到的,操作数据的程序设计方法在这两种格式中明显不同。
建议您安装 Android SDK version 1.5 或最新版以及 Eclipse 来运行本文附带的?示例代码。为了了解更多关于设置环境的知识,访问 Android Developers 网站。使用一个活动的帐户跟着示例练习是很重要的,但不是必须的。相关链接见?参考资料。
首先我们来简要的看一下这两个数据格式,从 XML 开始。如果您对 XML 和 JSON 已经很熟悉了,就可以跳转到?应用机会:Twitter feeds?在 Android 上开始运行。
XML:一个老朋友
不再是苦役当您将 XML 与 XML 普遍应用之前的工艺水平进行比较时,XML 的自述特性是很清楚的。此外,数据交换练习包括繁琐的数据描述文档,通常是在一个文字处理器或电子表格应用程序中手工编写的。这些文档,通常称为接口规范,描述了字段名、长度、分隔符、层次结构等等。用户采用他们认为合适的实践;最接近标准的是熟悉的逗号分隔值(CSV)模式,尽管 CSV 文件变化很大。如果您怀疑这一点,试着将一个 CSV 文件导入电子表格应用程序,并且注意所有可用选项。
事实上,近几年来为企业、web 或移动市场编程的人都遇到过 XML,几乎您见到的每个地方都有。
一个 XML 文档有一个可辨认的结构:一系列可以随意包含属性和子元素的元素。每个有效的 XML 文件第一行都有这样一个声明:<?xml version="1.0" encoding="utf-8"?>
。后面的内容根据应用程序而定。XML 的好处就在于它的自述性。
XML 模式
尽管 XML 文档是自述的,但也必须遵循一定的规则和指导方针,这就需要 XML 模式,它是一个描述特定 XML 文件结构的文档。此类结构通常是冗长且复杂的。(值得争议的是,XML 对 IT 领域最糟糕的贡献是,当高度描述的数据结构这一理念成为时尚时导致了数据爆炸,且这种情况由于过去十年中磁盘存储技术成本大幅降低而加剧。)
当这些大且复杂的文件变得更规范时,对程序员和分析员来说手工处理通常是不可能完成的。为了解决这个问题,XML 编辑器和验证工具可以在文件和相关的任务管理方面给予帮助。例如,文档和遗留格式转换。
除了一般的文本数据,XML 过去常用于存储二进制数据,通过一个称为?CDATA
?的特殊标记集合实现。一个 XML 文档中的?CDATA
?标记可能含有各种数据,包括其他标记文本,假设该文本本身不含有?CDATA
。
通过使用 XML 作为一个结构来执行请求/响应查询,这并不是 API 使用该功能的常用方式。响应数据经常包含一个包含在?CDATA
?标记中的 XML 结构。例如,一个 API 调用可能使用一个姓氏?Mott
?来请求一个客户记录。数据找到时,封装到一个 XML 结构中并将其置于响应元素中,如?清单 1?所示:
清单 1. 将数据封装到 XML 结构中并将其置于响应元素中?
?
工作空间中的 XML
今天,XML 是默认的、预定数据格式。尽管同一数据的其他格式也可用,但基于 XML 结构的可用性进行计划是一种最安全的方式。
Enterprise Resource Planning (ERP) 包频繁使用 XML 进行数据到任务的导入和导出。Internet 新闻网站经常将数据提供为 Really Simple Syndication (RSS) — 具有新闻阅读软件可以处理的预定义格式的 XML 文档。甚至文字处理应用程序(例如 OpenOffice.org 和 Microsoft? Office)也使用 XML。
现在的 Microsoft Office 文件是 PKZIP 兼容的,含有多个 XML 文档。 每个 XML 在第一行都有这个常见声明。正如您在?清单 2?所看到的,阅读这些属性可能有点难:
清单 2. 每个文件第一行的常见声明?
XML 是自述的,但是并不意味着标记一定是容易理解的。这个虚构的示例展示了多个名称空间的使用,多个名称使得理解 XML 文件更有挑战性,如果不使用专用工具就很难理解。
XML 随处可见,但是对于 Android 程序员来说并不是一个明智的选择,特别是,如果数据结构成为与 XML 结构伴随着的数据爆炸的牺牲品。像 Android 这样通常在蜂窝数据网络(cellular data network)上工作的资源受限平台不能存储和解析大量 XML 数据。然而,如果特殊编程任务要求文本和二进制数据交换,那么 XML 是一个可靠的选择。
现在,让我们看一看数据交换的另一个格式:JSON。
回页首
JSON:网络的新成员
越来越多的 Internet API 供应商提供 JSON 作为一种数据格式。JSON 在 Ajax (Asynchronous JavaScript and XML) 网页编程社区中享有盛名。Ajax 技术使 web 页面可以动态地更新,只更新所选区域的数据而不用更新整个页面。由于较少数据被传送 — 更重要的是,因为较少的数据被解析且显示在浏览器窗口 — 使用 AJAX 的应用程序比起传统 web 应用程序能够提供一个更好的用户体验。事实上,一个结构良好的 Ajax 应用程序可与智能或富客户端应用程序相抗衡。
当 Ajax 应用程序与 web 服务器交换数据时,经常需要某类数据的刷新,但不需要格式化。通常认为一个 web 服务器提供预格式化(preformatted)HTML 是一个糟糕的实践。相反的,一个格式良好的应用程序应该将数据内容发送到浏览器并应用一个 Cascading Style Sheets (CSS) 文件来产生视觉效果,比如颜色和特殊字体。
假设应用程序想要请求 Mr. Mott.(这是我们虚构的)的联系记录,应用程序返回浏览器的数据元素不止一个。它是如何包装的呢?在清单 1?示例中,您可以使用一个简单的请求/响应结构。这已经足够了;然而它要求您解析来自服务器的每个响应、以某种结构(DOM)存储数据,然后更新网页内容。
还有一种选择,您可以从服务器上返回一些 JavaScript,并用它来直接处理。以下是一个虚拟应用程序的样例响应,对 Mott 查询(
http://<yourserver/app/searchcontact?Mott
)的响应。这个响应是一个 JavaScript 对象字符串表示 — 即 JSON 字符串(为了适应本文页宽在这分成两行):?
注意,这个示例使用 JavaScript 函数?
eval()
?将字符串转换成一个 JavaScript 数组。JSON 库可以为执行该步骤提供更快更安全的方法,清单 3?中的方法并不是最佳实践。在这只是提供了一个 JSON 对象,如何用于 Ajax 应用程序的背景:JSON 结构可被客户端代码交换、解析和操作。总的来说,JSON 是:
CDATA
?对应模式。在?清单 3?中,客户端是一个运行客户端脚本的 web 浏览器。返回本文主题,接下来将研究在 Android 应用程序中 XML 和 JSON 的使用。
?
应用机会:Twitter feeds
Twitter 现在已经变成了一种国际力量,它提供的更新包罗万象:从什么人正在吃早饭,他们的孩子的球队在棒球比赛中的表现这类琐事,到封闭国家中的政治动 乱的街头新闻,器官移植实时报道等严肃话题。
要获取一些 XML 和 JSON 文档以用于本文附带的?样例代码,最简单的方法就是通过 URL http://twitter.com/statuses/user_timeline/userid.format,其中?userid?是您的 Twitter 用户 ID,format?是您要的格式:XML 或 JSON。
您也可以直接在您的 Twitte 页面上找到此页的链接,如?图 1?所示。在那里可以看到您的 Twitter 用户 ID。
图 1. 您 Twitter 页面上的 feed 页链接
完整的 feed 文件相当冗长,下面两个清单只显示 feed 的第一项(来自我的 Twitter 帐户)。清单 4?包含以下 XML 片段:
清单 4. XML 片段
?
清单 5?是同一数据,这次是以 JSON 格式显示:
清单 5. JSON 格式的 feed 数据?
注意,在两个清单中除了状态更新外还有非常多附加数据。您只需要注意日期/时间,何时发布公告以及公告的内容。接下来,将向您展示解析该数据的 Android 应用程序的相关部分。整个项目见?下载?部分。
?
XMLvsJSON 应用程序
真实的实时更新需要注意的是,样例应用程序没有实时地从 web 移动数据,尽管我们期盼一个真实应用程序。由于数据 feeds 取自原始资源文件夹,因此应用程序关注的是分析方面。关于使用 Android 进行网络连接相关信息的链接,见?参考资料。
Android 应用程序很简单。其中包含 XML 和 JSON 数据资料的全部副本。用户可以任选其一进行分析。?图 2?显示 Eclipse 中项目文件的结构。(查看?图 2 的文本版本。)
图 2. Eclipse 项目的文件结构图 3?显示选择解析选项之前的应用程序 UI:
图 3. 选择解析选项之前的应用程序 UI?应用程序 UI 有两个按钮,Parse XML 和 Parse JSON,接着是默认文本。清单 6?包含该 UI 的布局,在项目的 res/layout 文件夹中的 main.xml 中可以找到:
清单 6. UI 的布局?
Parse XML?和?Parse JSON file?按钮是在?
ScrollView
?之上定义的,ScrollView
?中含有一个?TextView
?控件。这里的意思是想要用户可以滚动结果数据。注意多个?
LinearLayout
?结构的使用。第一个是垂直对齐,其中既含有一个带有水平结构的?LinearLayout
?和一个?ScrollView
。内层LinearLayout
?含有两个?Button
?小部件。这个布局很冗长,一般在?onCreate()
?方法中调用,见?清单 7:
清单 7.?onCreate()
?方法?XML 解析
SAX 对 DOMAndroid 也支持一个 DOM 解析器,这需要占用较大的内存空间,但是降低在 SAX 解析器中的复杂性。对于 XMLvsJSON 这个应用程序,仅仅对大数据资源很小的一个子集感兴趣,SAX 方法可能是处理作业的最好工具。
XML 数据解析通常是使用一个 SAX 风格的解析器完成的。对于这类解析器,您可以建立一个?
InputSource
?指向源 XML 数据,并在文档 “运行” 时提供一个接收某些事件的处理程序。清单 8?展示examineXMLFile()
?方法,执行以下任务:
InputSource
SAXParser
,关联处理程序?twitterFeedHandler
(见?清单 9)TextView
?小部件中显示结果,在布局文件中作为?R.id.txtData
?识别,在代码中作为?tvData
?引用TextView
?中
清单 8.?examineXMLFIle()
?方法
?
清单 9?中有一些值得注意的细节,首先考虑到的是 SAX 解析器是一个基于事件的解析器,这就意味着使用 SAX 进行解析时要建立真实文件。在文档开始和结束、标记开始和结束、发现数据时,事件被触发。这意味着您必须定义一个数据结构来保留感兴趣的数据、抛弃余下的。
注意,使用?
StringBuilder
?和附加数据是因为一个特定数据在?InputSource
?上能通过多个读取来进行处理。千万不要以为所有数据都在给定的调用?characters()
?方法中提供。应用程序将数据收集到一个简单的格式化字符串中。而另一个示例中则是把这些实体放在一个集合类或数据库中,特别是如果有大量的操作都发生在解析之后。
getResults()
?方法是该类特有的,用来收集这类数据的集中表示法,并将其提供给应用程序,这不是?DefaultHandler
?接口的一部分。图 4?展示了已解析的 XML 数据。(查看?图 4 的文本版本。)
图 4. 已解析的 XML 数据尽管从构建、管理和导航结果结构方面来说,使用 SAX 解析器解析 XML 数据并不容易,但其主要优势是快速和极大地减少了解析过程中和解析之后的 RAM 需求数量。
现在看一下 Android 解析 JSON 数据的方法。
?
JSON 解析
在用户选择 JSON 按钮时解析 JSON 数据就开始了。调用?
examineJSONFile()
?方法,如?清单 10?所示。不需要额外的处理类。因为所有解析和文档管理都在 Android 提供的库中进行,所有 JSON 相关的代码都包含在这个方法中。
清单 10. 调用?examineJSONfile()
?方法?
像之前显示的 XML 例程一样,代码是从原始资源文件夹的文件中读取的。数据被整体读到内存中,转换成一个?
java.lang.String
,然后解析成?JSONArray
。要注意的是,正如此例所示,一个特殊的字符串能直接解析成一个数组,或者也可以直接解析成一个JSONObject
。因为 Twitter 数据是一个对象数组,整体解析成一个数组然后按顺序逐个访问对象是明智的选择。该方法的流程简单明了,一旦数据被解析,代码建立一个类似于 XML 解析器处理程序方法的字符串表示。有趣的是数据将由您来管理;您不需要建立额外内存结构来容纳数据,同样地,应用程序预先就知道在?
JSONArray
?中有多少个条目(在这个例子中是 20 个)。尽管 JSON 解析在编程上简单得多,但并不是没有代价的。它要增加内存消耗,在处理之前整体读取数据流并进行存储。相反的,SAX XML 方法仅使用相关数据。另外,如果解析特殊 JSON 对象的内存是足够的,则这个方法将很受应用程序欢迎,特别是,几乎不需要使用 DOM 的应用程序。
?
结束语
本文在 Android 应用程序背景下介绍了 XML 和 JSON 数据交换格式。比起 JSON 方法,XML 方法更快、内存受限更小 — 但是以增加复杂性为代价。在第二部分,我将介绍一些结合使用 JSON 方法的先进技术,例如,基于 WebKit 的 WebView 小部件,并为 Android 应用程序定制动态应用程序逻辑。
?