Tutorial: Requesting RESTful Web Services with JSON in your Android App

Web services make it easy for mobile devices to communicate with applications running on a web or application server. I am sharing my findings of how to implement an Android client for services implemented according to the Representational State Transfer (REST) approach. This little turorial shows how you send HTTP requests, parse JSON string responses and display the results in a ListActivity, showing a progress dialog while loading.

Required Permissions

Well, your App will need to connect to the internet in order to request your web services. This requires the permission android.permission.INTERNET.

Update your manifest XML file so that it registers the permission, like:

<uses-permission android:name="android.permission.INTERNET"/>

<application>
	<activity android:name=".activities.MyActivity" 
		android:permission="android.permission.INTERNET" />
</application>

JavaScript Object Notation (JSON)

JSON is a specified format for the exchange of structured data. The advantage of JSON, compared to XML, is the ability to not only provide primitive types, such as strings or numbers, but also objects and arrays. Some people consider JSON also as more leightweight and easier to read than XML. The syntax is the same like defining JavaScript objects as it is specified in ECMAScript (3rd edition).

This would be a valid JSON object:

{ 
	"customername": "Derp",
	"items": [
        {
            "id": 100,
            "name": "item X",
			"active": true,
			"categorieIds": [10,15,17]
        },
        {
            "id": 101,
            "name": "item Y",
			"active": false,
			"categorieIds": [11]
        }
    ]
}

James Clark compared XML and JSON in more detail and pointed out why also I considered to use JSON for my own web services: “By contrast with JSON, especially with a dynamic programming language, you can get a reasonable in-memory representation just by calling a library function”. You will see later what that means.

Requesting the Service

Android provides already two APIs with that you can send requests to web servers and handle their responses: Apache HTTP Client and HttpUrlConnection. According to the Android developers, HttpUrlConnection should be preferred due to more speed and less energy consumption.
If you still want to use Apache’s HTTP client, I recommend to have a look at their tutorial and how to set up a more stable client in your App. Also check David Chandler’s BasicHttpClient which he considers as simpler to use because it already implements all basic operations such as URL encoding, exception handling and reading the input stream.

This is how you get it running with HttpUrlConnection including place holders for some basic error handling:

public static JSONObject requestWebService(String serviceUrl) {
	disableConnectionReuseIfNecessary();

	HttpURLConnection urlConnection = null;
	try {
		// create connection
		URL urlToRequest = new URL(serviceUrl);
		urlConnection = (HttpURLConnection) 
			urlToRequest.openConnection();
		urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
		urlConnection.setReadTimeout(DATARETRIEVAL_TIMEOUT);
		
		// handle issues
		int statusCode = urlConnection.getResponseCode();
		if (statusCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
			// handle unauthorized (if service requires user login)
		} else if (statusCode != HttpURLConnection.HTTP_OK) {
			// handle any other errors, like 404, 500,..
		}
		
		// create JSON object from content
		InputStream in = new BufferedInputStream(
			urlConnection.getInputStream());
		return new JSONObject(getResponseText(in));
		
	} catch (MalformedURLException e) {
		// URL is invalid
	} catch (SocketTimeoutException e) {
		// data retrieval or connection timed out
	} catch (IOException e) {
		// could not read response body 
		// (could not create input stream)
	} catch (JSONException e) {
		// response body is no valid JSON string
	} finally {
		if (urlConnection != null) {
			urlConnection.disconnect();
		}
	}		
	
	return null;
}

/**
 * required in order to prevent issues in earlier Android version.
 */
private static void disableConnectionReuseIfNecessary() {
	// see HttpURLConnection API doc
	if (Integer.parseInt(Build.VERSION.SDK) 
			< Build.VERSION_CODES.FROYO) {
		System.setProperty("http.keepAlive", "false");
	}
}

private static String getResponseText(InputStream inStream) {
	// very nice trick from 
	// http://weblogs.java.net/blog/pat/archive/2004/10/stupid_scanner_1.html
	return new Scanner(inStream).useDelimiter("\\A").next();
}

Note that this sample only implements GET requests (reading data). However, you should not face any issues when adapting your code to support the other HTTP methods POST, PUT and DELETE. Budi Wibowo explains how he implemented POST requests submitting parameters.

Parsing JSON

As you can see in the code above, parsing a string and converting it into a JSON Java object requires nothing but one single line of code:

new org.json.JSONObject(stringToParse);

Having the web service outcome as JSON object enables you to access attribute values on it with methods like “.getInt(attributeName)” or “.getJSONArray(attrName)”. As an example, this is how your data access layer could be implemented:

public List<MyItem> findAllItems() {
	JSONObject serviceResult = WebServiceUtil.requestWebService(
		"http://url/to/findAllService");
	
	List<MyItem> foundItems = new ArrayList<MyItem>(20);
	
	try {
		JSONArray items = serviceResult.getJSONArray("items");
		
		for (int i = 0; i < items.length(); i++) {
			JSONObject obj = items.getJSONObject(i);
			foundItems.add(
					new Item(obj.getInt("id"), 
						obj.getString("name"), 
						obj.getBoolean("active")));
		}
		
	} catch (JSONException e) {
		// handle exception
	}
	
	return foundItems;
}

Check the org.json-API for more information.

Showing Progress Dialog

Now we improve our App by displaying a progress dialog while the service is processing in the background. Rama Mohan explains in his blog how to execute asynchronous tasks what I am applying to our service call here. Assuming we have a ListView displaying items which we want to request through our web service:

public class ItemsListActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
	    
	    new RequestItemsServiceTask().execute();
    }
    
	/**
	 * populate list in background while showing progress dialog.
	 */
    private class RequestItemsServiceTask 
			extends AsyncTask<Void, Void, Void> {
    	private ProgressDialog dialog = 
			new ProgressDialog(ItemsListActivity.this);
    	private List<MyItem> itemsList;

    	@Override
    	protected void onPreExecute() {
			// TODO i18n
    		dialog.setMessage("Please wait..");
    		dialog.show();
    	}
    	
    	@Override
    	protected Void doInBackground(Void... unused) {
			// The ItemService would contain the method showed
			// in the previous paragraph
        	ItemService itemService = ItemService.getCurrentInstance();
        	try {
        		itemsList = itemService.findAllItems();
    		} catch (Throwable e) {
    			// handle exceptions
    		}
    		return null;
    	}
    	
    	@Override
    	protected void onPostExecute(Void unused) {
    		
			// setListAdapter must not be called at doInBackground()
			// since it would be executed in separate Thread
    		setListAdapter(
				new ArrayAdapter<MyItem>(ItemsListActivity.this, 
            		R.layout.list_item, itemsList));
					
    		if (dialog.isShowing()) {
    			dialog.dismiss();
    		}
    	}
    }
}

Optimizing Web Services for Mobile Devices

Web service producers should keep the payload as small as possible in order to speed up clients, in particular mobile devices. They will appreciate every KByte they do not have to down- or upload. If you are designing your own web services for mobile devices, the following tips might help you.

  • Keep URLs short. Utilize URL-rewriting or use short proxy domains.
  • Provide only data which is actually required. You might provide different versions of the same service with more or less attributes.
  • Use attribute names of maximum two characters. You can map these names in your Java code to more descriptive constant names.
  • Remove unnecessary HTTP headers. For instance, PHP offers the function header_remove().
  • Do not render white spaces.
  • When delivering collections: Do not forget to set a maximum number of records. That is a little parameter which gets forgotten very often in real-world applications…
  • Follow some best practices when introducing new services.

Read also how to send POST requests with parameters.

Tags: , , , ,

12 responses to “Tutorial: Requesting RESTful Web Services with JSON in your Android App”

  1. Hugo Maurício says :

    Man, This is perfect. Thank you so much

  2. ElvenStar says :

    perfect
    Thank you

  3. Delly says :

    i’m sorry, is there any sample source code? i’m new comer in Android programming. maybe if you have the sample code (on github or send me by email), i can understand it deeply.
    Big thanks

  4. Francis says :

    perfect tutorial, i have a question, what if the service method has a request body in json format? what would be the modification for this code?

    thanks.

  5. bruce says :

    Well,this is what I‘m looking for. Thanks a lot.

  6. Sharan Dhanala says :

    Is there a way we can can keep the REST as background service for a android app so that I can regularly keep checking for new content added to the web service and in case it is added then I would pop up a notification.

  7. Kiran says :

    Excellent article !! Keep writing :)

  8. Madhu says :

    Hi,.. Nice Work Sir can You Put source code or complete the coded mentions erlier with screen shorts if possible then every one can under stand or if possible mail me,…

    I dont know where should i need to create a Json for android and how to do this for sever and client side,.. I f its possible Mail me,..

    Thank You,.. Nice Work,…

    ,.

  9. Stranger says :

    This is really a good tutorial. Thanks a lot dude! Keep up the good work.

  10. Priit Pärna says :

    Thanks a lot, helpful read for people moving away from DefaultHttpClient() :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: