This article is based on Android in Practice, to be published on Summer 2011. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) ebooks and pbooks. MEAPs are sold exclusively through Manning.com. All print book purchases include an ebook free of charge. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information.
Technique: Parsing JSON
Introduction
The AJAX(Asynchronous JavaScript and XML) craze that accompanied the rise of the Web 2.0 was a key element to giving modern websites a desktop application like user experience. Interestingly, just like the XMLHttpRequest object, AJAXmade another thing popular, one which had been around for years, but the full potential of which had never really been recognized: JSON, the JavaScript Object Notation. (Never before has the invention, or better, the discovery of a single class made so much difference!).
also read:
- How to set up android development environment?
- How to write AndroidManifest.xml?
- How to create a new activity in Android?
The AJAX(Asynchronous JavaScript and XML) craze that accompanied the rise of the Web 2.0 was a key element to giving modern websites a desktop application like user experience. Interestingly, just like the XMLHttpRequest object, AJAXmade another thing popular, one which had been around for years, but the full potential of which had never really been recognized: JSON, the JavaScript Object Notation. (Never before has the invention, or better, the discovery of a single class made so much difference!)
Problem
You want to integrate with a Web service that either only supports JSON or you specifically want to take advantage of JSON‘s benefits such as being able to efficiently create and manage textual representations of data structures in memory.
Solution
Before looking at the JSON API bundled with Android, let’s have a closer look at how JSON represents objects. If you’re already familiar with JavaScript, then this will, well, look familiar to you. If not, then JSON can still be quickly explained.
Basically, you can think of JSON objects as maps or object hashes. Starting with a single root element, other elements (the values) are mapped to identifiers (the keys). Here’s how this book could be modeled in JSON:
{ "title": "Android in Practice", "price": 49.99, "authors": [ { "name": "C. Collins" }, { "name": "M. Galpin" }, { "name": "M. Kaeppler } ] }
This simple data structure already combines all kinds of syntax elements JSON knows. Finally something that’s dead simple and tremendously useful at the same time, something you seldom find anymore in computers these days!
Curly braces in JSON demarcate objects. An object is a map: it maps keys (the quotes are mandatory) to values. A value can again be an object, a string (any value put in double quotes becomes a string), or a number (with or without decimal point). Moreover, a value can also be an array of any of these. Arrays are demarcated using square brackets.
Even though it’s simple enough, you don’t have to parse JSON documents yourself, of course. Android comes with the JSON implementation from JSON.org (the reference implementation), so you can use that straight away. Before showing you how to use it to parse JSON data, let’s suppose we get our data from the TMDb Web service, which incidentally also supports JSON. Let’s have a look at what the response to Movie.imdbLookup method looks like when requested as JSON (listing 1).
Listing 1 JSON response format of TMDb’s Movie.imdbLookup method
[ { "popularity":3, "translated":true, "adult":false, "language":"en", "original_name":"Inception", "name":"Inception", "alternative_name":"Eredet", "movie_type":"movie", "id":27205, "imdb_id":"tt1375666", "url":"http://www.themoviedb.org/movie/27205", "votes":52, "rating":9.0, "certification":"PG-13", "overview":"Dom Cobb (Leonardo DiCaprio) is a skilled thief, the best in the dangerous art of extraction: stealing valuable secrets from deep within the subconscious during the dream state when the mind is at its most vulnerable. ...", "released":"2010-07-16", "runtime":148, "version":226, "last_modified_at":"2010-08-19 16:04:03", … } ]
As we can see, the result is an array with a single element (since we’ve only requested a single movie), which represents the movie. Now we need to turn this into a Movie object, so we finally need to get hold of Android’s JSON parser. Listing 2 shows how that could look like.
Listing 2 JsonMovieParser.java parses a TMDb movie document using JSON
public class JsonMovieParser { public static Movie parseMovie(InputStream json) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(json)); StringBuilder sb = new StringBuilder(); #1 String line = reader.readLine(); while (line != null) { sb.append(line); line = reader.readLine(); } reader.close(); JSONArray jsonReply = new JSONArray(sb.toString()); #2 Movie movie = new Movie(); JSONObject jsonMovie = jsonReply.getJSONObject(0); #3 movie.setTitle(jsonMovie.getString("name")); movie.setRating(jsonMovie.getString("rating")); return movie; } } #1 Holds the server response as a string #2 Turns the response string into a JSONObject #3 Gets the movie JSONObject
The JSON parser relies on the data being in memory entirely, so we have to read the response string into a buffer first (#1). We can then use this string to instantiate a JSON object (a JSONArray in this case, since the root element is an array), which effectively parses the JSON string into an internal key-value map (#2). We’re interested in the first and only element of the array, so we get the JSONObject at position 0, which is the movie we’re after (#3). Any such JSONObject has accessor methods to read its values like strings, numbers, and other JSON objects or arrays.
Discussion
JSON is the most straightforward and simple way to parse a Web service response. It’s also efficient and lightweight: it’s basically nothing more than a Java HashMap mapping strings to other objects. If you can use the Java Map interface, then you can use Android’s JSON classes.
Of course an implication of this is that the json.org parser may not be the optimal choice if you need to consume really large documents, especially if you only want to access a tiny fraction of the information they contain. You probably don’t want to parse several megabytes of text into a JSON object, since it will be in memory all at once. In that case, XmlPull is probably your best bet. For anything else, the stock parser is a very good choice.
NOTE
If your documents are large, but you absolutely must rely on JSON for some reason (e.g. because the data you want to access is only available in JSON), you may want to look for a stream-based JSON parser like Jackson instead. This of course means adding another dependency to your project, so choose wisely.
There’s one subtlety you should be aware of when using Android’s JSON parser: You should always know upfront which values will be part of the response when you parse it. That’s because a JSONObject’s get*() methods will throw an exception if you try to access a field that is not there. For the elements that can exist in some responses but not in others (for optional elements), you should use the opt*() methods instead, which simply return null if the field you’re trying to access does not exist (in other words, use optString() instead of getString() for accessing an optional string field).
also read:
- How to set up android development environment?
- How to write AndroidManifest.xml?
- How to create a new activity in Android?
- Android Books
Summary
JavaScript is a very good choice for serializing data from a Web server to a JavaScript host environment such as a Web browser since a JSON server response can be executed by the client using JavaScript’s eval() function. JSON is the most straightforward and simple way to parse a Web service response. It’s also efficient and lightweight. If you can use the Java Map interface, then you can use Android’s JSON classes.