출처 : http://www.ibm.com/developerworks/xml/library/x-andbene1/index.html


Mobile devices and platforms boast more features and functionality with each new release, and often mere months separate significant announcements from the leading mobile vendors. The headlines are mostly about UI features (such as advanced multitouch capabilities and Adobe® Flash® technology) and hardware enhancements (such as processor speed and storage capacity). But the crucial fact remains that content is king. Content—or, more generally, data—is exchanged constantly among applications, servers, mobile devices, and users. Without being able to work with it, smartphones such as Apple's iPhone and Google's Android simply become overpriced and underperforming cell phones.

Frequently used acronyms

  • API: Application Programming Interface
  • DOM: Document Object Model
  • HTML: HyperText Markup Language
  • IDE: Integrated development environment
  • SAX: Simple API for XML
  • SDK: Software Developer Kit
  • UI: User Interface
  • XML: Extensible Markup Language

Consider the phenomenal success of social-networking platforms such as Facebook, LinkedIn, and Twitter. From a pure feature-and-function perspective, these platforms are largely pedestrian. They are popular because members and site visitors derive value from the content published there. And that content is accessed increasingly by mobile devices.

This article demonstrates the use of XML and JSON data-interchange formats on the Android platform. The source of the data for the example application is a status-update feed for a Twitter account. The feed data is available from Twitter in both XML and JSON formats. As you'll see, the programming approach to manipulating the data varies significantly between the two formats.

I suggest you have the Android SDK version 1.5 or later installed along with Eclipse to run the example code that accompanies this article. To learn more about setting up your environment, visit the Android Developers website. It is also helpful, but not required, to have an active Twitter account to follow along with the example. See Resources for relevant links.

I'll begin with a brief look at both data formats, starting with XML. If you're already familiar with XML and JSON, you can safely skip to Application opportunity: Twitter feeds to start working with them on Android.

XML: An old friend

No more hard labor

The value of XML's self-describing nature is clear when you contrast it to the state of the art before XML's general adoption. Then, data-interchange exercises included laborious data-description documents, often written and maintained by hand in a word processor or spreadsheet application. These documents, commonly known as interface specifications, depicted field names, lengths, delimiters, hierarchies, and so on. Users followed practices as they saw fit; the closest thing to a standard was the familiar comma-separated-value (CSV) format. Even CSV files vary a good deal. If you doubt it, try to import one into a spreadsheet program and notice all of the options available.

Virtually anyone who has done programming for the enterprise, web, or mobile markets in recent years has encountered XML. It is just about everywhere you look.

An XML document has a recognizable structure: a series of elements that can optionally contain attributes and child elements. Every valid XML document begins with a declaration on the first line: <?xml version="1.0" encoding="utf-8"?>. What comes after the first line is application-dependent. The beauty of XML is that it is self-describing.

XML schemas

Although XML documents are self-describing, they must follow certain rules and guidelines. This is where the XML schema comes in. It is a document that describes the structure of a particular XML file. Such structures are often verbose and complex. (Arguably, XML's worst contribution to the IT field is the data explosion that took place once the idea of highly descriptive data structures came into fashion, fueled in part by the greatly reduced cost of disk-storage technology in the past decade.)

As these large and complex files became more the norm, the art of working on them manually was often a nonstarter for programmers and analysts. To address this issue, XML editors and validating tools became available to aid in the management of the files and the tasks relating to them, such as documentation and conversion to legacy formats.

In addition to general text data, XML can also be used to store binary data through a special set of tags known as CDATACDATAtags within an XML document can contain any kind of data, including other mark-up text, provided that text does not contain CDATAitself.

It's not uncommon for APIs to leverage this capability by using XML as a structure for performing request/response queries. Often the response data contains an XML structure contained within a CDATA tag. For example, an API call might request a customer record with a last name equaling Mott. When the data is found, it is packaged into an XML structure and placed within the response element, as in Listing 1:


Listing 1. Packaging data into an XML structure and placing it within the response element
<?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 in the workplace

Today XML is the default, expected data format. Although the same data might be available in other formats too, it is a safe bet to plan on the availability of an XML structure.

Enterprise Resource Planning (ERP) packages use XML heavily for data import and export tasks. Internet news sites often make data available as Really Simple Syndication (RSS) feeds—XML documents with a predefined format that news readers are set up to process. Even word-processing applications such as OpenOffice.org and Microsoft® Office use XML.

Today's Microsoft Office documents are PKZIP-compatible files containing multiple XML documents. Each XML file shares the common declaration in the first line. As you can see in Listing 2, the attributes can be somewhat hard to follow:


Listing 2. Common declaration in the first line of each XML file
 <?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 is self-describing, but that doesn't mean that the tags are necessarily easy to decipher. This cryptic example also demonstrates the use of multiple XML namespaces, which can make XML documents even more challenging to follow without specialized tools.

XML is everywhere, but it can often be a poor choice for an Android programmer, particularly if the data structure has fallen victim to the data explosion often associated with XML structures. A resource-constrained platform such as Android, which is usually working on a cellular data network, cannot store and parse massive amounts of XML data. However, if a particular programming task requires the interchange of both text and binary data, XML can be a solid choice.

Now you'll look at an alternative data-interchange format: JSON.

JSON: New kid on the Net

More and more Internet API providers are offering JSON as a data-format option. JSON made a name for itself in the Ajax (Asynchronous JavaScript and XML) web-programming community. Ajax technology enables web pages to update dynamically by refreshing data in selected pockets rather the entire page. Because less data is transferred—and, more important, because much less data is parsed and drawn to the browser window—an Ajax-enabled application can provide a much better user experience than a traditional web application. In fact, a well-written Ajax application can rival smart- or fat-client applications in user experience.

When an Ajax application exchanges data with a web server, it is often requesting a refresh of some kind of data, but ideally without the formatting. It is generally considered poor practice for a web server to serve up preformatted HTML. Instead, a well-written application should send data content to the browser and apply a Cascading Style Sheets (CSS) file to provide visual effects such as colors and font particulars.

Suppose an application wants to request a contact record for our mythical Mr. Mott. The application has more than one data element to send back to the browser. So how does it get packaged? In the Listing 1 example, you might use a simple request/response structure in XML. This is perfectly adequate; however, it requires that you parse each response from the server, store the data in a structure of some sort (a DOM), and then update the web-page content.

Alternatively, you can simply get some JavaScript back from the server and work directly with it. Here is a sample response from a hypothetical application responding to a query (http://<yourserver/app/searchcontact?Mott) for a man named Mott. The response is a string representation of a JavaScript object—that is, a JSON string (split into two lines here to fit this article's page width):

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

Whereas XML is known for its verbosity, JSON has a reputation for being somewhat hard to read. JSON objects are constructed in a key:value pair format. The object's elements are separated by commas, and each object is contained within curly braces {}. An array of objects is contained within square brackets. This is a common approach to transferring a series of rows from a database to an array of objects in which each array element corresponds to a database row, and each property of the object represents a column of data.

Listing 3 shows an example of using this kind of object within an HTML page. For simplicity, the server communications are not included; instead, the JSON data is provided as a string variable named serverresponse.


Listing 3. Using a JSON object within an HTML page
<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>

Note that this example uses the JavaScript function named eval() to turn a string into a JavaScript array. JSON libraries are available to provide faster and more secure methods of performing this step. The approach in Listing 3 is not a best practice. I provide it here to give some context to how a JSON object can be used in an Ajax application: The JSON structure is exchanged, parsed, and manipulated by the client code.

In summary, JSON is:

  • A data-interchange format.
  • A means to encode JavaScript objects as strings.
  • Limited to text and numeric values. Binary values are explicitly not permitted. JSON has no CDATA equivalent.
  • More economical than XML in terms of data size, at the expense of readability.
  • Increasingly available as an option from API providers such as Twitter.

In Listing 3 the client is a web browser running client-side scripting. Returning to this article's focus, next you'll examine the use of XML and JSON in an Android application.

Application opportunity: Twitter feeds

Twitter has become an international force, providing updates on everything from what people are having for breakfast and how their kid's sports team is faring at the ballpark, to serious topics such as street-level updates on political revolts in closed nations or a play-by-play of an organ transplant.

The easiest way to get to get the XML and JSON documents to use with the sample code accompanying this article is through the URL http://twitter.com/statuses/user_timeline/userid.format, where userid is your own Twitter user ID and format is either XML or JSON.

You can also find a link to this page directly on your Twitter page, as in Figure 1. You can see your Twitter user ID there.


Figure 1. Link to feeds page on your Twitter page
Screen capture of fableson Twitter page with a link 'RSS fee of fableson's tweets' in lower right corner 

The complete feed files are very verbose, so the next two listings show only the first entry of the feed (from my own Twitter account). Listing 4 contains the XML snippet:


Listing 4. The XML snippet
<?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>

Listing 5 shows the same data, this time in JSON format:


Listing 5. Feed data in JSON format
[
{"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..."}
]

Notice how much extra data is included in both listings beyond the mere status update. All you need to care about is the date/time when the post was made and the text from the post itself. Next I'll show you the pertinent portions of an Android application that parses this data. The full project is available for download.

The XMLvsJSON application

Real-world real-time updates

Note that the sample application does not pull the data in real time from the web, though that would be the expectation for a real-world application. The data feeds are taken out of the raw resources folder so the application can focus on the parsing aspects. SeeResources for links to information on making network connections with Android.

The Android application is simple. It contains full copies of the XML and JSON data feeds and gives the user the option of parsing either one. Figure 2 shows the structure of the project files within Eclipse. (View a text-only version of Figure 2.)


Figure 2. File structure of the Eclipse project
Screen capture of  the structure of the files within Eclipse 

Figure 3 shows the application's UI prior to the selection of a parsing option:


Figure 3. The application's UI prior to selection of a parsing option
Screen capture of the application's user interface prior to selecting a parsing option 

The application UI shows two buttons, Parse XML and Parse JSON file, followed by default text. Listing 6 contains the layout for this UI, found in the main.xml file in the res/layout folder of the project:


Listing 6. The layout for the UI
<?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>

The Parse XML and Parse JSON file buttons are defined above a ScrollView, which in turn contains a TextView control. The idea here is that you want the user to be able to scroll through the resulting data.

Note the use of multiple LinearLayout structures. The first is a vertical alignment, and it contains both a LinearLayout with a horizontal structure and a ScrollView. The inner LinearLayout contains the two Button widgets. This layout is inflated and wired up in the onCreate() method, in Listing 7:


Listing 7. The onCreate() method
    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();
            }
        });

    }

The examineXMLFile() method controls the XML parsing.

XML parsing

SAX versus DOM

Android also supports a DOM parser, which requires a larger memory footprint but reduces some of the complexity found in the SAX parser. For an application such as XMLvsJSON, which is only interested in a very small subset of a large data feed, the SAX approach is likely the better tool for the job.

Parsing of XML data is often done with a SAX-style parser. With this style of parser, you set up an InputSource pointing to the source XML data and provide a handler that receives certain events as the document is "walked." Listing 8 shows the examineXMLFile()method, which takes care of the following tasks:

  • Sets up the InputSource with the XML file from the raw resources
  • Creates a SAXParser, associated with a handler namedtwitterFeedHandler ( in Listing 9)
  • Invokes the parser and displays the results in a TextViewwidget identified in the layout file as R.id.txtData and referenced in the code as tvData
  • Shows any errors, also in the TextView

Listing 8. The examineXMLFIle() method
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());
        }
    }

Whereas examineXMLFile() sets things up, the real parsing work from the perspective of the application takes place in the handler that's implemented in the twitterFeedHandler.java file. This class, which implements the DefaultHandler interface, is inListing 9:


Listing 9. The twitterFeedHandler class
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);
        }
    }

}

Listing 9 contains some noteworthy items. The first thing to consider is that the SAX parser is an event-based parser, which means that you build the actual document as it is parsed. Events are fired whenever the document starts, the document ends, a tag starts, a tag ends, and data is found. This implies that you must define a data structure to keep the data of interest and discard the rest.

Note the StringBuilder and the appending of data, used because a particular data element can be processed across multiple reads on the InputSource. Never assume that all of the data is provided in any given call to the characters() method.

This application collects the data into a simply formatted string. An alternative example might include putting these entries into a collection class or database instead, particularly if a great deal of manipulation were to take place after the parse.

The getResults() method is custom to this class. It's used to gather the assembled representation of this data and provide it to the application. It is not part of the DefaultHandler's interface.

Figure 4 depicts the parsed XML data. (View a text-only version of Figure 4.)


Figure 4. The parsed XML data
Screen capture of the parsed XML data on a mobile phone screen 

Although parsing XML with the SAX parser is nontrivial in terms of building up, managing, and navigating the resulting structure, its main advantages are speed and the opportunity to reduce significantly the amount of RAM required both during and after the parsing step.

Now you'll take a look at Android's approach to parsing JSON data.

JSON parsing

Parsing JSON data in the application starts when the user selects the JSON button. This invokes the examineJSONFile() method, in Listing 10. No additional handler class is required, because all parsing and document management take place within the Android-supplied libraries, and all JSON-related code is contained in this method.


Listing 10. Invoking the examineJSONfile() method
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());
        }
    }

Like the XML routine shown previously, this code reads in a file from the raw resources. The data is read into memory in its entirety, converted to a java.lang.String, and then parsed into a JSONArray. Note that a particular string can be parsed directly into an array, as in this example, or the string can be parsed into a JSONObject. Because the Twitter data is an array of objects, it makes sense to parse the entire string into an array and then access the object individually by ordinal position.

This method's flow is straightforward; once the data is parsed, the code builds up a string representation that's similar to the approach of the XML parser handler. Of interest here is that the data is managed for you; you don't need to build up additional memory structures to contain the data. Likewise, the application knows up front just how many entries are in the JSONArray (20 in this example).

Although JSON parsing is much more simple programmatically, it is not cost-free. It adds the burden of memory consumption for reading in the entire data stream before it can be worked on, and for storing all of the data. In contrast, the SAX XML approach uses only the data of interest. That caveat aside, if memory for parsing a particular JSON object is ample, this approach can be favorable for many applications, particularly if working with the DOM is of little interest.

'Android > Tip&Tech' 카테고리의 다른 글

android change titlebar diynamic  (0) 2011.06.14
Fixed header in a TableLayout  (1) 2011.06.14
android HTTP GET,POST Examples  (0) 2011.06.10
[펌]ViewFlipper 관한 설명(추천)  (0) 2011.06.09
progressbar 배경 및 색깔 바꾸기  (0) 2011.06.09

+ Recent posts