Sử dụng XML và JSON với Android, Phần 1: Khám phá những lợi ích của JSON và XML trong các ứng dụng Android

Hãy xem xét cả hai định dạng trao đổi dữ liệu với nhau của XML và JSON để sử dụng trên nền tảng Android

Trong bài viết hai phần này, hãy tìm hiểu các kỹ thuật dùng để xử lý hai trong số các định dạng dữ liệu phổ biến nhất được sử dụng trên Internet — XML (Ngôn ngữ đánh dấu mở rộng) và JSON (Ký hiệu đối tượng JavaScript) — trên nền tảng Android. Phần đầu tiên này trình bày các vấn đề cơ bản của XML và JSON và cho bạn biết cách xây dựng một ứng dụng Android có phân tích cú pháp và hiển thị một nguồn cung cấp tin cập nhật-trạng thái Twitter được cung cấp theo cả hai định dạng.

Frank Ableson, Thiết kế phần mềm

Sau khi sự nghiệp trong đội bóng rổ của trường cao đẳng kết thúc mà không có một hợp đồng dài hạn nhiều năm chơi cho đội LA Lakers, Frank Ableson đã chuyển chí hướng của mình sang thiết kế phần mềm máy tính. Ông thích giải quyết các vấn đề phức tạp, nhất là trong các lĩnh vực truyền thông và lập giao diện phần cứng. Khi không làm việc, ông dành thời gian với người vợ Nikki và con cái. Bạn có thể gặp Frank tại địa chỉ frank@cfgsolutions.com.



24 08 2010 (Xuất bản lần đầu tiên vào ngày 12 07 2011)

Các bài viết khác trong loạt bài này

Các thiết bị và các nền tảng di động khoe khoang có thêm nhiều tính năng và chức năng hơn cho mỗi bản phát hành mới và thường chỉ là các thông báo chào hàng quan trọng riêng biệt mỗi tháng của các nhà cung cấp di động hàng đầu. Các tin quan trọng chủ yếu là về các tính năng giao diện người dùng (như là các khả năng đa chạm cao cấp và công nghệ Adobe® Flash®) và các nâng cấp phần cứng (như tốc độ của bộ vi xử lý và dung lượng bộ nhớ). Nhưng sự thực quan trọng vẫn còn nguyên vẹn đó là nội dung là vua. Nội dung — hay nói chung là dữ liệu — được trao đổi liên tục giữa các ứng dụng, các máy chủ, các thiết bị di động và người dùng. Nếu không có khả năng làm việc với nó, thì các máy điện thoại thông minh như iPhone của Apple và Android của Google chỉ đơn giản trở thành các điện thoại di động giá cao và kém hiệu quả.

Frequently used acronyms

  • API: Application Programming Interface-Giao diện lập trình ứng dụng.
  • DOM: Document Object Model-Mô hình đối tượng tài liệu.
  • HTML: HyperText Markup Language-Ngôn ngữ đánh dấu siêu văn bản.
  • IDE: Integrated development environment-Môi trường phát triển tích hợp.
  • SAX: Simple API for XML-API đơn giản cho XML.
  • SDK: Software Developer Kit-Bộ công cụ của nhà phát triển phần mềm.
  • UI: User Interface-Giao diện người dùng.
  • XML: Extensible Markup Language-Ngôn ngữ đánh dấu mở rộng

Hãy xem xét sự thành công kỳ lạ của các nền tảng nối mạng xã hội như Facebook, LinkedIn và Twitter. Từ góc độ tính năng và chức năng thuần túy, các nền tảng này khá tẻ nhạt. Chúng trở nên phổ biến vì các thành viên và khách truy cập tìm thấy giá trị từ nội dung được công bố ở đó. Và nội dung đó được các thiết bị di động truy cập ngày càng tăng.

Bài viết này trình bày cách sử dụng các định dạng trao đổi dữ liệu XML và JSON trên nền tảng Android. Nguồn dữ liệu cho ứng dụng ví dụ là một nguồn cung cấp dữ liệu cập nhật-trạng thái cho một tài khoản Twitter. Dữ liệu cung cấp có sẵn từ Twitter theo cả hai định dạng XML và JSON. Như bạn sẽ thấy, cách tiếp cận lập trình để xử lý dữ liệu thay đổi đáng kể giữa hai định dạng này.

Tôi đề nghị bạn có phiên bản 1.5 hoặc mới hơn của Android SDK được cài đặt cùng với Eclipse để chạy mã ví dụ kèm theo bài viết này. Để tìm hiểu thêm về việc thiết lập môi trường của bạn, hãy truy cập vào trang Web của các nhà phát triển Android. Không bắt buộc nhưng sẽ rất có ích nếu có một tài khoản Twitter đang hoạt động để làm theo cùng với ví dụ này. Xem phần Tài nguyên để tìm các liên kết có liên quan.

Tôi sẽ bắt đầu bằng xem xét nhanh cả hai định dạng dữ liệu, bắt đầu với XML. Nếu bạn đã quen thuộc với XML và JSON, bạn có thể yên tâm bỏ qua và chuyển ngay đến mục Thời cơ của ứng dụng: Các nguồn cung cấp tin của Twitter để bắt đầu làm việc với chúng trên Android.

XML: Một người bạn cũ

Không còn phải lao động vất vả hơn nữa

Giá trị của bản chất tự mô tả của XML trở nên rõ ràng khi bạn đối chiếu nó với tình trạng công nghệ cao trước khi chấp nhận phổ biến XML. Lúc đó, hàng loạt các hoạt động trao đổi-dữ liệu bao gồm các tài liệu mô tả dữ liệu nặng nề, thường được viết và được duy trì thủ công theo một ứng dụng trình xử lý văn bản hoặc ứng dụng bảng tính. Những tài liệu này, thường được gọi là các đặc tả kỹ thuật của giao diện, mô tả các tên trường, độ dài, các dấu phân cách, các hệ thống phân cấp và v.v.. Những người dùng đã làm theo những thói quen mà họ thấy phù hợp nhất; định dạng gần nhất với tiêu chuẩn là định dạng các giá trị phân cách bằng dấu phẩy (CSV) quen thuộc. Thậm chí các tệp CSV giống nhau cũng thay đổi nhiều. Nếu bạn nghi ngờ điều này, hãy cố gắng nhập khẩu một tệp vào một chương trình bảng tính và chú ý đến tất cả các tùy chọn có sẵn.

Hầu như bất cứ ai đã thực hiện lập trình cho doanh nghiệp, Web hoặc các thị trường di động trong những năm gần đây đều đã bắt gặp XML. XML đúng là có mặt ở khắp mọi nơi mà bạn thấy.

Một tài liệu XML có cấu trúc có thể dễ nhận biết: đó là một loạt các phần tử theo tùy chọn có thể chứa các thuộc tính và các phần tử con. Mỗi tài liệu XML hợp lệ bắt đầu bằng một khai báo trên dòng đầu tiên: <?xml version="1.0" encoding="utf-8"?>. Cái gì tiếp tục sau dòng đầu tiên phụ thuộc vào ứng dụng. Vẻ đẹp của XML là ở chỗ nó tự mô tả.

Các lược đồ XML

Mặc dù các tài liệu XML tự mô tả, những chúng phải tuân theo các quy tắc và các hướng dẫn cụ thể. Đây là nơi lược đồ XML phát huy tác dụng. Lược đồ XML là một tài liệu mô tả cấu trúc của một tệp XML cụ thể. Các cấu trúc như vậy thường dài dòng và phức tạp. (Người ta có thể cho rằng, một đóng góp tồi tệ nhất của XML trong lĩnh vực công nghệ thông tin là sự bùng nổ dữ liệu xẩy ra một khi ý tưởng về các cấu trúc dữ liệu có tính mô tả cao đã trở thành mốt, hơn nữa được thúc đẩy một phần nhờ việc giảm đáng kể chi phí của công nghệ lưu trữ-trên đĩa trong thập kỷ qua).

Khi các tệp lớn và phức tạp ấy trở thành chuẩn nhiều hơn, thì nghệ thuật làm việc thủ công với các tệp đó thường không có triển vọng thành công với các lập trình viên và các nhà phân tích. Để giải quyết vấn đề này, các trình soạn thảo và các công cụ xác nhận hợp lệ của XML đã trở nên có sẵn để hỗ trợ trong việc quản lý các tệp và các nhiệm vụ liên quan đến chúng, như làm tài liệu và chuyển đổi về các định dạng kế thừa.

Ngoài các dữ liệu văn bản nói chung, XML cũng có thể được sử dụng để lưu trữ dữ liệu nhị phân thông qua một tập hợp các thẻ đặc biệt gọi là CDATA. Các thẻ CDATA trong một tài liệu XML có thể chứa bất kỳ loại dữ liệu nào, bao gồm văn bản đánh dấu khác, miễn là chính văn bản này không chứa CDATA của nó.

Không còn là hiếm khi mà các API sử dụng khả năng này bằng cách sử dụng XML như là một cấu trúc để thực hiện các truy vấn yêu cầu/đáp ứng. Thường thì các dữ liệu đáp ứng chứa một cấu trúc XML bên trong một thẻ CDATA. Ví dụ, một lời gọi API có thể yêu cầu một bản ghi khách hàng có họ là Mott. Khi tìm thấy dữ liệu, nó sẽ được đóng gói thành một cấu trúc XML và được đặt trong phần tử đáp ứng, như trong Liệt kê 1:

Liệt kê 1. Đóng gói dữ liệu thành một cấu trúc XML và đặt nó bên trong phần tử đáp ứng
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request>
<query>
<lastname>Mott</lastname>
<maxhits>100</maxhits>
</query>
</request>

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<returncode>200</returncode>
<query>
<lastname>Mott</lastname>
<hits>1</hits>
</query>
<data>
<![CDATA[
<contact>
<firstname>Troy</firstname>
<lastname>Mott</lastname>
<age>not telling</age>
</contact>
]]>
</data>
</response>

XML tại nơi làm việc

Hiện nay XML là dạng dữ liệu mặc định, được mong đợi. Mặc dù cùng một dữ liệu có thể cũng có sẵn trong các định dạng khác, để đảm bảo an toàn nên lập kế hoạch sẵn sàng xử lý một cấu trúc XML.

Các gói ERP (Enterprise Resource Planning – Lập kế hoạch nguồn lực cho doanh nghiệp) sử dụng chủ yếu XML cho các nhiệm vụ nhập khẩu và xuất khẩu dữ liệu. Các trang Web tin tức trên Internet thường tạo sẵn dữ liệu như là các nguồn cấp tin RSS (Really Simple Syndication - Sự cung cấp thực sự đơn giản) — đây là các tài liệu XML có một khuôn dạng định sẵn mà các trình đọc tin đã biết cách xử lý. Ngay cả các ứng dụng xử lý văn bản như OpenOffice.org và Microsoft® Office cũng sử dụng XML.

Các tài liệu của Microsoft Office hiện nay là các tệp tương thích với PKZip có chứa nhiều tài liệu XML. Mỗi tệp XML chia sẻ khai báo chung ở dòng đầu tiên. Như bạn thấy trong Liệt kê 2, các thuộc tính có thể hơi khó theo dõi:

Liệt kê 2. Khai báo chung ở dòng đầu tiên của mỗi tệp XML
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
 xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math"
 xmlns:v="urn:schemas-microsoft-com:vml"
 xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"
 xmlns:w10="urn:schemas-microsoft-com:office:word"
 xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
 xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
 <w:body><w:p w:rsidR="00B6337C" w:rsidRDefault="00663F0E"><w:r>
 <w:t xml:space="preserve">This is a sample </w:t></w:r><w:r
 w:rsidRPr="006906EA"><w:rPr><w:i/></w:rPr><w:t>Microsoft 
 Word document</w:t></w:r><w:r><w:t xml:space="preserve"> used
 to </w:t></w:r><w:r w:rsidRPr="006906EA"><w:rPr><w:b/>
 <w:u w:val="single"/></w:rPr><w:t>demonstrate</w:t></w:r>
 <w:r><w:t xml:space="preserve"> some XML topics.</w:t></w:r>
 </w:p><w:p w:rsidR="00B14B2A" w:rsidRDefault="00B14B2A"/><w:p 
 w:rsidR="00B14B2A"w:rsidRDefault="00B14B2A"><w:r><w:rPr>
 <w:noProof/></w:rPr><w:drawing><wp:inline distT="0" distB="0" 
 distL="0" distR="0"><wp:extent cx="3276600" cy="3838575"/><wp:effectExtent
 l="19050" t="0" r="0" b="0"/><wp:docPr id="1" name="Picture 0"
 descr="frankableson.jpg"/><wp:cNvGraphicFramePr><a:graphicFrameLocks
 xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
 noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic
 xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData
 uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic
 xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
 <pic:nvPicPr><pic:cNvPrid="0"name="frankableson.jpg"/><pic:cNvPicPr/>
 </pic:nvPicPr><pic:blipFill><a:blip r:embed="rId4"
 cstate="print"/><a:stretch><a:fillRect/></a:stretch>
 </pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/>
 <a:ext cx="3276600" cy="3838575"/></a:xfrm><a:prstGeom
 prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic>
 </a:graphicData></a:graphic></wp:inline></w:drawing>
 </w:r></w:p><w:p w:rsidR="00663F0E" w:rsidRDefault="00663F0E"/>
 <w:p w:rsidR="00CC16CE" w:rsidRDefault="00CC16CE"/><w:sectPr 
 w:rsidR="00CC16CE" w:rsidSect="00B6337C"><w:pgSz w:w="12240" w:h="15840"/>
 <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" 
 w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid
 w:linePitch="360"/></w:sectPr></w:body></w:document>

XML tự mô tả, nhưng điều đó không có nghĩa là các thẻ nhất thiết phải dễ giải mã. Ví dụ khó hiểu này cũng trình diễn cách sử dụng nhiều vùng tên XML, có thể làm cho các tài liệu XML thậm chí trở nên khó theo dõi hơn nhiều nếu không có các công cụ chuyên dụng.

XML có ở khắp mọi nơi, nhưng nó thường có thể là một sự lựa chọn tồi cho một lập trình viên Android, đặc biệt là khi cấu trúc dữ liệu đã là nạn nhân của sự bùng nổ dữ liệu thường đi liền với cấu trúc XML. Một nền tảng hạn chế nguồn lực như Android, thường đang làm việc trên một mạng dữ liệu di động, không thể lưu trữ và phân tích cú pháp một lượng lớn dữ liệu XML. Tuy nhiên, nếu một nhiệm vụ lập trình cụ thể yêu cầu trao đổi cả hai dữ liệu văn bản và dữ liệu nhị phân, thì XML có thể là một sự lựa chọn chắc chắn.

Bây giờ bạn sẽ xem xét một định dạng trao đổi dữ liệu thay thế: JSON.


JSON: Người mới trên Net

Ngày càng có nhiều nhà cung cấp API Internet đang đề nghị dùng JSON như là một tùy chọn định dạng dữ liệu. JSON đã tạo dựng tiếng tăm cho mình trong cộng đồng lập trình Web Ajax (Asynchronous JavaScript and XML - JavaScript không đồng bộ và XML). Công nghệ Ajax cho phép các trang Web cập nhật dữ liệu động bằng cách làm mới dữ liệu trong các túi đã chọn thay vì toàn bộ trang. Vì chỉ có ít dữ liệu được chuyển — và quan trọng hơn, vì chỉ có rất ít dữ liệu được phân tích cú pháp và được đưa tới cửa sổ trình duyệt — một ứng dụng được Ajax cho phép có thể mang lại một trải nghiệm người dùng tốt hơn nhiều so với một ứng dụng Web truyền thống. Trong thực tế, một ứng dụng được viết bằng Ajax có thể sánh ngang với các ứng dụng máy khách thông minh hoặc ứng dụng máy khách phong phú (fat-client) theo trải nghiệm của người dùng.

Khi một ứng dụng Ajax trao đổi dữ liệu với một máy chủ Web, nó thường yêu cầu làm mới một số loại dữ liệu, nhưng lý tưởng là dữ liệu không định dạng. Nói chung, người ta thường coi việc cho một máy chủ Web phục vụ dạng HTML định dạng sẵn là một cách làm tồi. Thay vào đó, một ứng dụng được viết đúng cách nên gửi nội dung dữ liệu tới trình duyệt và áp dụng một tệp CSS (Cascading Style Sheets - Các bản định kiểu chồng nhau) để cung cấp hiệu ứng trực quan như các chi tiết màu sắc và phông chữ.

Giả sử một ứng dụng muốn yêu cầu một bản ghi địa chỉ liên lạc với ông Mott theo tưởng tượng của chúng ta. Ứng dụng này có nhiều hơn một phần tử dữ liệu gửi trở lại trình duyệt. Vậy nó được đóng gói như thế nào? Trong ví dụ của Liệt kê 1, bạn có thể sử dụng một cầu trúc yêu cầu/đáp ứng đơn giản bằng XML. Điều này là hoàn toàn thỏa đáng; tuy nhiên, nó yêu cầu bạn phải phân tích cú pháp từng đáp ứng từ máy chủ, lưu trữ dữ liệu theo một cấu trúc dạng nào đó (ví dụ DOM - Mô hình đối tượng tài liệu) và sau đó cập nhật nội dung trang Web.

Một cách làm khác là bạn có thể chỉ cần nhận một JavaScript nào đó trả về từ máy chủ và làm việc trực tiếp với nó. Đây là một đáp ứng mẫu từ một ứng dụng giả định sẽ đáp ứng cho truy vấn (http://<yourserver/app/searchcontact?Mott) tìm một người tên là Mott. Đáp ứng này là một biểu diễn chuỗi ký tự của một đối tượng JavaScript — đó là, một chuỗi JSON (ở đây chia thành hai dòng cho khớp với chiều rộng trang của bài viết này):

[{"firstname":"Troy","lastname":"Mott","age":"don't ask!"},{"firstname":"Apple seed",
   "lastname":"Mott's","age":"99"}]

Trong khi XML đã được biết là khá dài dòng, thì JSON có tiếng là hơi khó đọc. Các đối tượng JSON được xây dựng theo định dạng một cặp khóa:giá trị. Các phần tử của đối tượng được phân cách bằng dấu phẩy và mỗi đối tượng được chứa trong các dấu ngoặc nhọn {}. Một mảng các đối tượng được chứa trong các dấu ngoặc vuông. Đây là một cách tiếp cận phổ biến để chuyển một loạt các hàng từ cơ sở dữ liệu đến một mảng các đối tượng trong đó mỗi phần tử mảng tương ứng với một hàng cơ sở dữ liệu và mỗi đặc tính của đối tượng biểu diễn một cột dữ liệu.

Liệt kê 3 cho thấy một ví dụ về sử dụng loại đối tượng này trong một trang HTML. Để đơn giản, nó không bao gồm các giao tiếp máy chủ; thay vào đó, dữ liệu JSON được cung cấp như một biến chuỗi ký tự có tên là serverresponse.

Liệt kê 3. Sử dụng một đối tượng JSON trong một trang HTML
<html>
<head>
<script language="JavaScript">
var serverresponse = "[{\"firstname\":\"Troy\",\"lastname\":\"Mott\",\"age\":\"don't
ask!\"},{\"firstname\":\"Apple seed\",\"lastname\":\"Mott's\",\"age\":\"99\"}]";
function updatepage()
{
    var contacts = eval(serverresponse );
    var i;
    var s = "Search Results:<br />";
    for (i=0;i<contacts.length;i++)
    {
        s = s + contacts[i].firstname + " " + contacts[i].lastname + "'s age is ... " 
+ contacts[i].age + "<br />";
    }
    document.getElementById("target").innerHTML = s;
}
</script>
</head>
<body>
<button onclick="updatepage();">Search for Mott</button><br />
<span id="target">&nbsp;</span>
</body>
</html>

Lưu ý rằng ví dụ này sử dụng hàm JavaScript có tên là eval() để chuyển một chuỗi ký tự thành một mảng JavaScript. Các thư viện JSON có sẵn để cung cấp các phương thức thực hiện bước này nhanh hơn và an toàn hơn. Cách tiếp cận trong Liệt kê 3 không phải là một cách làm tốt nhất. Tôi đưa nó ra ở đây để cung cấp một vài ngữ cảnh về cách sử dụng một đối tượng JSON trong một ứng dụng Ajax: cấu cấu trúc JSON được trao đổi, phân tích cú pháp và thao tác bởi mã phía máy khách.

Tóm lại, JSON là:

  • Một định dạng trao đổi dữ liệu với nhau.
  • Một phương tiện để mã hóa các đối tượng JavaScript như là các chuỗi ký tự.
  • Bị hạn chế chỉ gồm các giá trị văn bản và số. Các giá trị nhị phân rõ ràng không được phép. JSON không có kiểu CDATA tương đương.
  • Kinh tế hơn so với XML về kích thước dữ liệu, nhưng lại trả giá bằng khó đọc.
  • Ngày càng trở nên một tùy chọn có sẵn của các nhà cung cấp API như Twitter.

Trong Liệt kê 3 khách là một trình duyệt Web đang chạy kịch bản lệnh phía máy khách. Hãy quay trở lại trọng tâm của bài viết này, tiếp theo bạn sẽ kiểm tra việc sử dụng XML và JSON trong một ứng dụng Android.


Thời cơ của ứng dụng: Nguồn cấp dữ liệu Twitter

Twitter đã trở thành một lực lượng quốc tế, cung cấp các thông tin cập nhật về tất cả mọi thứ từ mọi người đang có gì cho bữa ăn sáng và đội thể thao của con cái họ đang chơi ra sao ở sân bóng chày, đến các chủ đề nghiêm túc như các thông tin cập nhật tại đường phố về cuộc nổi loạn chính trị ở các quốc gia bảo thủ hoặc một bài tường thuật tại chỗ về cấy ghép nội tạng.

Cách dễ nhất để có được các tài liệu XML và JSON để sử dụng với mã mẫu kèm theo bài viết này là thông qua URL http://twitter.com/statuses/user_timeline/userid.format, ở đây userid là mã định danh (ID) người dùng Twitter riêng của bạn và format (định dạng) hoặc là XML hoặc là JSON.

Bạn cũng có thể tìm thấy một liên kết trực tiếp đến trang này trên trang Twitter của bạn, như trong Hình 1. Bạn có thể thấy ID người dùng Twitter của bạn ở đó.

Hình 1. Liên kết với trang các nguồn cấp dữ liệu trên trang Twitter của bạn
Anh chụp màn hình trang Twitter của fableson có một liên kết 'trả phí RSS cho các bài viết ngắn trên tweeterr của fableson' ở góc dưới bên phải

Các tệp nguồn cấp dữ liệu đầy đủ rất dài dòng, do đó hai liệt kê tiếp theo chỉ hiển thị mục nhập đầu tiên của nguồn cấp (từ tài khoản Twitter của riêng tôi). Liệt kê 4 chứa đoạn mã XML:

Liệt kê 4. Đoạn mã XML
<?xml version="1.0" encoding="UTF-8"?>
<statuses type="array">
<status>
  <created_at>Thu Apr 29 05:25:29 +0000 2010</created_at>
  <id>13052369631</id>
  <text>Wrapping up new article on JSON for Android
 programmers...</text>
  <source><a href="http://www.linkedin.com/"rel="nofollow">
   LinkedIn</a></source>
  <truncated>false</truncated>
  <in_reply_to_status_id/>
  <in_reply_to_user_id/>
  <favorited>false</favorited>
  <in_reply_to_screen_name/>
  <user>
    <id>15221439</id>
    <name>fableson</name>
    <screen_name>fableson</screen_name>
    <location>Byram Township, NJ</location>
    <description/>

<profile_image_url>http://a3.twimg.com/profile_images/260492935
/bookcover_normal.jpg</profile_image_url>
    <url>http://msiservices.com</url>
    <protected>false</protected>
    <followers_count>52</followers_count>
    <profile_background_color>9ae4e8
    <profile_text_color>000000</profile_text_color>
    <profile_link_color>0000ff</profile_link_color>
    <profile_sidebar_fill_color>e0ff92
</profile_sidebar_fill_color>
    <profile_sidebar_border_color>87bc44
</profile_sidebar_border_color>
    <friends_count>10</friends_count>
    <created_at>Tue Jun 24 17:04:11 +0000 2008</created_at>
    <favourites_count>0</favourites_count>
    <utc_offset>-18000</utc_offset>
    <time_zone>Eastern Time (US & Canada)</time_zone>

   <profile_background_image_url>http://s.twimg.com/a/1272044617/
images/themes/theme1/bg.png</profile_background_image_url>
   
<profile_background_tile>false</profile_background_tile>
    <notifications>false</notifications>
    <geo_enabled>false</geo_enabled>

    <verified>false</verified>
    <following>false</following>
    <statuses_count>91</statuses_count>
    <lang>en</lang>
    <contributors_enabled>false</contributors_enabled>
  </user>
  <geo/>
  <coordinates/>
  <place/>
  <contributors/>
</status>
</statuses>

Liệt kê 5 cho thấy cùng một dữ liệu, lúc này theo định dạng JSON:

Liệt kê 5. Nguồn cấp dữ liệu theo định dạng JSON
[
{"in_reply_to_status_id":null,
"favorited":false,
"created_at":"Thu Apr 29 05:25:29 +0000 2010",
"in_reply_to_screen_name":null,
"geo":null,
"source":"<a href=\"http://www.linkedin.com/\" rel=\"nofollow\
          ">LinkedIn</a>",
"contributors":null,
"place":null,
"truncated":false,
"coordinates":null,
"user":
{
    "friends_count":10,
    "description":"",
    "lang":"en",
    "statuses_count":91,
    "time_zone":"Eastern Time (US & Canada)",
    "profile_link_color":"0000ff",
    "favourites_count":0,
    "created_at":"Tue Jun 24 17:04:11 +0000 2008",
    "contributors_enabled":false,
    "profile_sidebar_fill_color":"e0ff92",
    "following":null,
    "geo_enabled":false,
    "profile_background_image_url":"http://s.twimg.com/a/1272044617/images/themes
/theme1/bg.png",
    "profile_image_url":"http://a3.twimg.com/profile_images/260492935
/bookcover_normal.jpg",
    "notifications":null,
    "profile_sidebar_border_color":"87bc44",
    "url":"http://msiservices.com",
    "verified":false,
    "profile_background_tile":false,
    "screen_name":"fableson",
    "protected":false,
    "location":"Byram Township, NJ",
    "profile_background_color":"9ae4e8",
    "name":"fableson",
    "followers_count":52,
    "id":15221439,
    "utc_offset":-18000,
    "profile_text_color":"000000"
},
"in_reply_to_user_id":null,
"id":13052369631,
"text":"Wrapping up new article on JSON for Android programmers..."}
]

Hãy lưu ý có bao nhiêu dữ liệu được thêm vào trong cả hai danh sách ngoài việc chỉ cập nhật trạng thái. Tất cả mọi thứ mà bạn cần phải quan tâm hơn về chúng là ngày/giờ khi thực hiện đăng lên và bản thân văn bản gửi đăng đó. Tiếp theo tôi sẽ chỉ cho bạn những phần cần thiết của một ứng dụng Android để phân tích cú pháp dữ liệu này. Toàn bộ dự án có sẵn để tải về.


Ứng dụng XML so với JSON

Các cập nhật thời gian thực thế giới thực

Lưu ý rằng ứng dụng mẫu không kéo dữ liệu theo thời gian thực từ trang Web, mặc dù đó sẽ là sự kỳ vọng đối với một ứng dụng thế giới thực. Các nguồn cấp dữ liệu được lấy ra khỏi thư mục tài nguyên thô để cho ứng dụng có thể tập trung vào các khía cạnh phân tích cú pháp. Xem phần Tài nguyên để biết các liên kết đến các thông tin về việc tạo các kết nối mạng bằng Android.

Ứng dụng Android đơn giản. Nó chứa các bản sao đầy đủ của các nguồn cấp dữ liệu XML và JSON và cung cấp cho người dùng tùy chọn phân tích cú pháp một trong hai nguồn đó. Hình 2 cho thấy cấu trúc của các tệp dự án trong Eclipse. (Xem phiên bản chỉ có văn bản của Hình 2.)

Hình 2. Cấu trúc tệp của dự án Eclipse
Ảnh chụp màn hình về cấu trúc của các tệp trong Eclipse

Hình 3 cho thấy giao diện người dùng của ứng dụng trước khi lựa chọn một tùy chọn phân tích cú pháp:

Hình 3. Giao diện người dùng của ứng dụng trước khi lựa chọn một tùy chọn phân tích cú pháp
Ảnh chụp màn hình về vác giao diện người dùng của ứng dụng trước khi chọn tùy chọn phân tích cú pháp

Giao diện người dùng của ứng dụng hiển thị hai nút ấn, Parse XML (Phân tích cú pháp XML) và Parse JSON file (Phân tích cú pháp tệp JSON), tiếp theo là văn bản mặc định. Liệt kê 6 chứa cách bố trí cho giao diện người dùng này, có trong tệp main.xml trong thư mục res/layout của dự án:

Liệt kê 6. Cách bố trí cho giao diện người dùng
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal">

<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
 android:id="@+id/btnXML" android:text="Parse XML"></Button>
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
 android:id="@+id/btnJSON" android:text="Parse JSON file"></Button>
</LinearLayout>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/ScrollView01" android:layout_width="fill_parent"
android:layout_height="wrap_content">

<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="default text" 
    android:layout_gravity="center_horizontal"
    android:id="@+id/txtData" 
    />


</ScrollView>

</LinearLayout>

Các nút ấn Parse XMLtệp Parse JSON được định nghĩa trên một ScrollView, rồi đến ScrollView chứa một thành phần điều khiển TextView. Ý tưởng ở đây là bạn muốn người dùng có thể cuộn qua dữ liệu kết quả.

Lưu ý việc sử dụng nhiều cấu trúc LinearLayout. Đầu tiên là dóng thẳng theo chiều dọc và nó bao gồm cả hai, một LinearLayout có một cấu trúc ngang và một ScrollView. LinearLayout bên trong chứa hai widget Button. Cách bố trí này được mở rộng và được nối đến phương thức onCreate(), trong Liệt kê 7:

Liệt kê 7. Phương thức onCreate()
    Button btnXML;
    Button btnJSON;
    TextView tvData;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        tvData = (TextView) findViewById(R.id.txtData);
        btnXML = (Button) findViewById(R.id.btnXML);
        btnXML.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View v)
            { 
                examineXMLFile();
            }
        });


        btnJSON = (Button) findViewById(R.id.btnJSON);
        btnJSON.setOnClickListener(new Button.OnClickListener()
        {
            public void onClick(View v)
            {
                examineJSONFile();
            }
        });

    }

Phương thức examineXMLFile() điều khiển phân tích cú pháp XML.


Phân tích cú pháp XML

SAX so với DOM

Android cũng hỗ trợ một trình phân tích cú pháp DOM (Mô hình đối tượng tài liệu), đòi hỏi một vùng bộ nhớ lớn hơn, nhưng làm giảm đi một số sự phức tạp có trong trình phân tích cú pháp SAX. Đối với một ứng dụng như là XML so với JSON, chỉ quan tâm tới một tập con rất nhỏ của một nguồn cấp dữ liệu lớn, cách tiếp cận SAX có thể là công cụ tốt hơn cho công việc này.

Việc phân tích cú pháp dữ liệu XML thường được thực hiện bằng một trình phân tích cú pháp theo phong cách SAX. Với trình phân tích cú pháp theo phong cách này, bạn thiết lập một InputSource trỏ đến dữ liệu XML nguồn và cung cấp một trình xử lý để tiếp nhận một số sự kiện nhất định khi tài liệu này "được đi qua dần từng bước." Liệt kê 8 cho thấy phương thức examineXMLFile(), giải quyết các nhiệm vụ sau đây:

  • Thiết lập InputSource với tệp XML từ các tài nguyên thô.
  • Tạo một SAXParser, liên kết với một trình xử lý có tên là twitterFeedHandler (trong Liệt kê 9)
  • Gọi trình phân tích cú pháp và hiển thị các kết quả trong một widget TextView được xác định trong tệp bố trí như là R.id.txtData và được tham chiếu như tvData trong các mã.
  • Hiển thị bất kỳ lỗi nào, cũng trong TextView.
Liệt kê 8. Phương thức examineXMLFIle()
void examineXMLFile()
    {
        try {
            InputSource is = new InputSource(getResources()
.openRawResource(R.raw.xmltwitter));
            // create the factory
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // create a parser
            SAXParser parser = factory.newSAXParser();
            // create the reader (scanner)
            XMLReader xmlreader = parser.getXMLReader();
            // instantiate our handler
            twitterFeedHandler tfh = new twitterFeedHandler();

            // assign our handler
            xmlreader.setContentHandler(tfh);
            // perform the synchronous parse
            xmlreader.parse(is);
            // should be done... let's display our results
            tvData.setText(tfh.getResults());
        }
        catch (Exception e) {
            tvData.setText(e.getMessage());
        }
    }

Trong khi phương thức examineXMLFile() thiết lập những thứ này, thì việc phân tích cú pháp thực từ phối cảnh của ứng dụng diễn ra trong trình xử lý được cài đặt trong tệp twitterFeedHandler.java. Lớp này, cài đặt giao diện DefaultHandler, trong Liệt kê 9:

Liệt kê 9. Lớp twitterFeedHandler
public class twitterFeedHandler extends DefaultHandler {

    StringBuilder sb = null;
    String ret = "";
    boolean bStore = false;
    int howMany = 0;

    twitterFeedHandler() {
    }

    String getResults()
    {
        return "XML parsed data.\nThere are [" + howMany + "] status updates\n\n" + ret;
    }
    @Override

    public void startDocument() throws SAXException {
        // initialize "list"
    }

    @Override
    public void endDocument() throws SAXException {

    }

    @Override
    public void startElement(String namespaceURI, String localName, String qName, 
Attributes atts) throws SAXException {

        try {
            if (localName.equals("status")) {
                this.sb = new StringBuilder("");
                bStore = true;
            }
            if (localName.equals("user")) {
                bStore = false;
            }
            if (localName.equals("text")) {
                this.sb = new StringBuilder("");
            }
            if (localName.equals("created_at")) {
                this.sb = new StringBuilder("");
            }
        } catch (Exception ee) {

            Log.d("error in startElement", ee.getStackTrace().toString());
        }
    }

    @Override

    public void endElement(String namespaceURI, String localName, String qName)
throws SAXException {

        if (bStore) {
            if (localName.equals("created_at")) {

                ret += "Date: " + sb.toString() + "\n"; 
                sb = new StringBuilder("");
                return;

            }

            if (localName.equals("user")) {
                bStore = true;
            }

            if (localName.equals("text")) {

                ret += "Post: " + sb.toString() + "\n\n";
                sb = new StringBuilder("");
                return;

            }


        }
        if (localName.equals("status")) {
            howMany++;
            bStore = false;
        }
    }

    @Override

    public void characters(char ch[], int start, int length) {

        if (bStore) {
            String theString = new String(ch, start, length);

            this.sb.append(theString);
        }
    }

}

Liệt kê 9 có chứa một số mục đáng chú ý. Mục đầu tiên cần xem xét là trình phân tích cú pháp SAX là một trình phân tích cú pháp dựa trên sự kiện, có nghĩa là bạn xây dựng tài liệu thực tế khi nó được phân tích cú pháp. Các sự kiện được châm ngòi mỗi khi bắt đầu tài liệu, kết thúc tài liệu, bắt đầu một thẻ, kết thúc một thẻ và tìm thấy dữ liệu. Điều này ngụ ý rằng bạn phải định nghĩa một cấu trúc dữ liệu để giữ lại dữ liệu quan tâm và loại bỏ phần còn lại.

Lưu ý StringBuilder và việc nối thêm dữ liệu, được sử dụng vì một phần tử dữ liệu cụ thể có thể được xử lý qua nhiều lần đọc trên InputSource. Không bao giờ giả định rằng tất cả dữ liệu được cung cấp trong một cuộc gọi cụ thể bất kỳ đến phương thức characters().

Ứng dụng này thu thập dữ liệu thành một chuỗi có định dạng đơn giản. Một ví dụ khác có thể bao gồm việc đặt những mục nhập này vào một lớp hoặc cơ sở dữ liệu sưu tập để thay thế, nhất là khi rất nhiều thao tác cần phải làm sau khi phân tích cú pháp.

Phương thức getResults() là tùy chỉnh cho lớp này. Nó được sử dụng để tập hợp kết quả thu thập được về dữ liệu này và cung cấp nó cho ứng dụng. Nó không phải là một phần của giao diện của DefaultHandler.

Hình 4 mô tả dữ liệu XML được phân tích cú pháp. (Xem một phiên bản chỉ có văn bản của Hình 4.)

Hình 4. Dữ liệu XML được phân tích cú pháp
Ảnh chụp màn hình về dữ liệu XML được phân tích cú pháp trên màn hình điện thoại di động

Mặc dù việc phân tích cú pháp XML với trình phân tích cú pháp SAX là rất quan trọng về xây dựng, quản lý và chuyển hướng cơ cấu kết quả, nhưng lợi thế chính của nó là tốc độ và cơ hội để làm giảm đáng kể số lượng bộ nhớ RAM cần thiết cả trong và sau bước phân tích cú pháp.

Bây giờ bạn sẽ xem xét một cách tiếp cận của Android để phân tích cú pháp dữ liệu JSON.


Việc phân tích cú pháp JSON

Việc phân tích cú pháp dữ liệu JSON trong ứng dụng này bắt đầu khi người sử dụng chọn nút JSON. Thao tác này gọi ra phương thức examineJSONFile(), trong Liệt kê 10. Không cần lớp của trình xử lý bổ sung thêm nào, vì tất cả việc phân tích cú pháp và quản lý tài liệu xảy ra trong các thư viện do Android-cung cấp và tất cả các mã có liên quan đến-JSON được chứa trong phương thức này.

Liệt kê 10. Gọi phương thức examineJSONfile()
void examineJSONFile()
    {
        try
        {
            String x = "";
            InputStream is = this.getResources().openRawResource(R.raw.jsontwitter);
            byte [] buffer = new byte[is.available()];
            while (is.read(buffer) != -1);
            String jsontext = new String(buffer);
            JSONArray entries = new JSONArray(jsontext);

            x = "JSON parsed.\nThere are [" + entries.length() + "]\n\n";

            int i;
            for (i=0;i<entries.length();i++)
            {
                JSONObject post = entries.getJSONObject(i);
                x += "------------\n";
                x += "Date:" + post.getString("created_at") + "\n";
                x += "Post:" + post.getString("text") + "\n\n";
            }
            tvData.setText(x);
        }
        catch (Exception je)
        {
            tvData.setText("Error w/file: " + je.getMessage());
        }
    }

Giống như thường trình XML được chỉ ra ở trên, đoạn mã này đọc vào một tệp từ các tài nguyên thô. Dữ liệu được đọc trọn vẹn vào bộ nhớ, được chuyển đổi thành một java.lang.String và sau đó được phân tích cú pháp trong một JSONArray. Lưu ý rằng một chuỗi ký tự cụ thể có thể được phân tích cú pháp trực tiếp trong một mảng, như trong ví dụ này, hoặc chuỗi ký tự đó có thể được phân tích cú pháp trong một JSONObject. Vì dữ liệu Twitter là một mảng các đối tượng, thật có ý nghĩa để phân tích cú pháp toàn bộ chuỗi trong một mảng và sau đó truy cập từng đối tượng theo vị trí thứ tự.

Dòng phương thức này đơn giản; một khi dữ liệu được phân tích cú pháp, mã này dựng lên một biểu diễn chuỗi ký tự tương tự như cách tiếp cận của trình xử lý của trình phân tích cú pháp XML. Vấn đề quan tâm ở đây là ở chỗ dữ liệu được quản lý cho bạn, bạn không cần phải xây dựng các cấu trúc bộ nhớ bổ sung để chứa dữ liệu. Tương tự như vậy, ứng dụng biết trước sẽ chỉ có bao nhiêu mục nhập trong JSONArray (trong ví dụ này là 20).

Mặc dù việc phân tích cú pháp JSON đơn giản hơn rất nhiều về lập trình, những nó không phải miễn phí. Nó bổ sung thêm gánh nặng tiêu thụ bộ nhớ để đọc toàn bộ luồng dữ liệu trước khi có thể tiếp tục chạy và để lưu trữ tất cả dữ liệu. Ngược lại, cách tiếp cận XML của SAX chỉ sử dụng dữ liệu đang quan tâm. Ngoài lời cảnh báo đó, nếu bộ nhớ dùng để phân tích cú pháp một đối tượng JSON cụ thể là dư thừa, thì cách tiếp cận này có thể được ưa chuộng hơn cho nhiều ứng dụng, đặc biệt là khi ít quan tâm làm việc với DOM.


Kết luận

Các bài viết khác trong loạt bài này

Bài viết này đã giới thiệu các định dạng trao đổi dữ liệu với nhau của XML và JSON trong ngữ cảnh của một ứng dụng Android. So với cách tiếp cận JSON, cách tiếp cận XML có phần nhanh hơn và ít bị hạn chế về bộ nhớ hơn — những trả giá bằng sự phức tạp hơn. Trong Phần 2, tôi sẽ giới thiệu một số các kỹ thuật tiên tiến kết hợp dữ liệu JSON, các widget WebView dựa trên WebKit và logic của ứng dụng tùy chỉnh động cho các ứng dụng Android.


Tải về

Mô tảTênKích thước
Article source codexmlvsjosn.zip68KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Nguồn mở
ArticleID=715458
ArticleTitle=Sử dụng XML và JSON với Android, Phần 1: Khám phá những lợi ích của JSON và XML trong các ứng dụng Android
publish-date=08242010