Building a REST Android Client Application

Craig Isakson Software Engineer

marketing + technology 701.235.5525 | 888.9.sundog | fax: 701.235.8941 2000 44th st s | floor 6 | fargo, nd 58103 www.sundog.net

it is important to understand what a resource is. After the application was paused. they will need to make another callout. but also limited network connectivity and power. REST is a broadly adopted architecture style that consists of clients and servers. store the response from the server in memory. an understanding of mobile and the Android activity/service lifecycle is a must. Worse yet. if the object is a user. it is human nature to take the path of least resistance. which would require more callouts to the REST service to retrieve the same information the user just had. A resource can be described as a particular object’s properties. pause and destroy. the resource would contain all the pertinent information about the user: name. The server will then respond to the client with the representation of the resource. 2 . For example. The garbage collector would destroy the application and when the user re-opens. Building the application this way would produce an application that was fast and would work most of the time. In the previous example of the REST application.. Another downside to this is that extra callouts consume more data as well as more battery.Building a REST Android Client Application | Craig Isakson As the number of smartphone and Android devices rise. Another use case that would have issues would be if the application had all the data it needed and was simply paused by the user opening a different application. the application being able to display data to the user is not guaranteed. the main activity would simply spin off a new thread for the callout. a mobile phone has limited resources. the application would make a callout each time the data needed to be displayed. With the previous example of the REST application. Since the REST callout can take some time to complete. the phone would then start to run out of memory. An activity has a number of different states including running. The garbage collector would go out looking for places to free up memory. when building a REST Android Client Application it may make sense to run the entire application inside of the main activity. address. the application would not be saved. applications that consume RESTful web services also rise. Activities with no services attached are the first to get destroyed when trying to free up memory. All the information that was retrieved from the sever for that callout will be lost and when the user returns to the application. An activity has its own lifecycle. These resources are not just limited by processing power and memory. the application’s state is switched to a pause mode. Clients make requests to the server to get or change the particular state of a resource. title. resume. etc. Why is building an application this way bad? In order to answer this. JSON and Binary. Unlike a typical desktop computer. and update the information within the activity when it is finished. the user would have no way of knowing if the information was successfully changed or submitted. if the user was updating information on the server through a POST or Delete. Since the data is dependent on network access. and often include an ID for reference to that particular user. Typically. It will focus on design patterns. platform integration and performance issues specific to the Android platform. Therefore. Another issue to consider when dealing with mobile is that a connection to the network is not always guaranteed. To fully understand this. if the application is currently making a callout to get or change information on the server and the user receives an incoming phone call. What is REST? REST stands for Representational State Transfer. There are a number of different ways a REST Android Application can be built and this white paper will present architectural considerations for developing RESTful applications on the Android platform. The REST API can describe the resource to the user in a number of different ways including XML.

The service runs in the context of the main UI thread. It is also ideal to use the Apache HTTP client build into Android and not the Java URL connection. This method should also fire back a Java listener callback. The first piece of the pattern that will be discussed is the RESTMethod. This means for each RESTMethod call there will be two database transactions: one when the call is made and one when the call has finished.Building a REST Android Client Application | Craig Isakson There are better ways to make REST callouts in Android. it should always be run in a worker thread. it would help to know what a service is. so it makes it very simple to retry an operation which means no loss of data for the user. In an effort to describe the above design pattern. A service is a facility for the application to tell the operating system about a process it wants to run in the background. Since this method can often take some time. Code samples will also be shown where applicable from the Android User Group of MN sample application that they have available on GitHub. the data and the state is still there. It is a passive data structure holding an abstract action that can be performed often between different applications and activities. The RESTMethod is an entity which actually prepares the HTTP URL & HTTP request body. and a database to maintain the state of the data being handled in the application. If the service is going to perform long running processes. it could simple query the database for the most up-to-date information. Below is a diagramed overview depicting the flow of his design. and processes the HTTP response. The next piece of the design pattern is the processor. An intent is an abstract description of an operation to be performed. The schema of the data in the database should match the resource on the server with the addition of two columns. 3 . There is a lot of confusion around in which thread the service runs. these processes should be started in a worker thread. The reason for the extra columns is to give the activity information on the state of the particular resource. This allows the application to continue to function and not have to focus on what is happening with that resource. The role of the processor is to mirror the state of the resource from the server on the device. the following example will start at the bottom and work its way up through the different pieces explaining what they are and how they work. if the application needs to find out what the current state of that resource is. Another benefit to using these flags is when a transaction was not successful. Since this is a service based API. so simply starting a service does not start a new thread. The easiest to implement is a design pattern created by Virgil Dobjanschi of Google. intents. In one of his design patterns. This means that the application will use a database to save the information. At any time. An intent is used to perform late runtime binding between the code in different applications. executes the HTTP transaction. the developer of the application would use services. This API will also use intents. a status column for describing the state of the resource and a response column used to save the response received from the server for that resource.

On the forward path. The most difficult to handle is when the activity is paused and the request is completed while the activity is paused. the service helper will handle the callback from the service and dispatch callbacks to the user interface listeners. it is now possible to run through a full example from activity to RESTMethod and back. the activity can simply query the database to retrieve the information. This is fairly simple and can be handled directly with the listener that was created. Since intents are being used to start the service. adding the operation type and unique request id. or when. This operation listener would use a request id to determine the state of the resource. all database operations should be performed within the context of a worker thread. The first is that the activity is still active when the request completes. Within the activity. this listener would need to be added to the onResume method in the activity and removed from the onPause method within the activity. other applications need more device resources. calling the startService(intent). The next piece of the design pattern is the service. all of the long running operations within the service need to be within the context of a worker thread. there needs to be an operation listener to essentially determine if the service has been completed. It is also important to stop the service whenever it has completed the callback to the service helper. The service helper will prepare and send the service request by checking if the method is already pending. since the data has already been saved to the database within the processor. Also. The service helper’s job is to provide a simple asynchronous API to the user interface. adding the binder callback. the service receives the intent sent by the service helper and starts the corresponding RESTMethod. It receives all the information it needs from the intent that was passed to it. adding the method specific parameters. Once the user interface knows that the request is complete. The next piece of the design pattern is the service helper. The activity will make a simple call to the service helper to add the comment with all the data that is needed: 4 . This example will use ‘add a comment to a picture’ as the sample objective. On the return path. The activity will then resume and check to see if the callout was completed. This is also fairly simple as the listener that was added in the onResume method would handle this use case. The service is there to allow long running operations to be performed while the activity is long gone. the service handles the processor callback and invokes the Service Helper binder callback. creating the request intent. Android will see that the service is up and running and if. the service itself is stateless. It would discover that the callout was completed and since the response from the RESTMethod was stored in the database for that particular resource. The second is that the activity is paused then resumed while the request completes. and returning the request id. they will be unable to receive them because the service is still sitting in memory. There are a few different use cases that must be considered when dealing with the request. On the return path. Now that each specific portion of the design pattern has been explained. The final piece of the design pattern is the activity. This makes it easy for the user interface to call the service methods and not focus on the state of the data. If the service is not stopped.Building a REST Android Client Application | Craig Isakson Just like with the RESTMethods. Just like the RESTMethod and the processor. the main activity can retrieve the data.

the service helper will take the request and package it up into an intent and send it off to the service. intent.mAppContext. ServiceContract. -1). ResultReceiver serviceHelperCallback = requestIntent.mAppContext.EXTRA_REQUEST_PARAMETERS). Bundle parameters = requestIntent. From here.SERVICE_CALLBACK_EXTRA.RESOURCE_TYPE_EXTRA.EXTRA_REQUEST_PARAMETERS. } Intent intent = new Intent(this. the service can process the intent that was sent from the service helper and start the processor to start processing the callout. Bundle requestParams = new Bundle(). intent. serviceCallback). requestParams.Building a REST Android Client Application | Craig Isakson mServiceHelper.PICTURE_ID.toString()).putString(CommentsTable. intent.putExtra(ServiceContract.getParcelableExtra(ServiceContract. mServiceClass).RESOURCE_TYPE_COMMENTS).COMMENT_TEXT. ResourceProcessor processor = ProcessorFactory.putExtra(ServiceContract. intent. return requestId.getInstance(this).SERVICE_ CALLBACK_EXTRA). The service will also check to see what type of operation is being performed (get. this.putString(CommentsTable. requestParams. intent.startService(intent).getStringExtra(ServiceContract. pictureId).submitNewComment(this.Id.METHOD_POST).putExtra(ServiceContract.RESOURCE_TYPE_EXTRA.putExtra(EXTRA_REQUEST_ID. put.METHOD_EXTRA. synchronized (pendingRequestsLock) { pendingRequests. comment. comment). requestId). String method = requestIntent. The service will return the request id. requestParams). String comment) { long requestId = generateRequestID().add(requestId).putExtra(ServiceContract.getProcessor(resourceType). ServiceContract. 5 .getIntExtra(ServiceContract. } Now that the service helper has put together the intent and started the service with the intent. which can be used later to check the status of the request: public long submitNewComment(String catId.getBundleExtra(ServiceContract. or delete) to determine what it needs to send back to the service helper: @Override protected void onHandleIntent(Intent requestIntent) { // Get request data from Intent int resourceType = requestIntent.METHOD_EXTRA).

} else if(serviceHelperCallback != null) { serviceHelperCallback. and insert the result * on success Parsing the JSON response (on success) and inserting into * the content provider */ addNewComments(result. } else if (method.Building a REST Android Client Application | Craig Isakson if (processor == null){ if(serviceHelperCallback != null){ serviceHelperCallback. apiPicId).equalsIgnoreCase(METHOD_POST)){ processor.send(REQUEST_INVALID. Bundle params) { // (1) Call the REST method // Create a RESTMethod class that knows how to assemble the URL. String apiPicId = getPicRefid(mPictureId). The processor will use the callback from the RESTMethod to update the state once again and return the results back to the service: @Override public void getResource(ResourceProcessorCallback callback.getString(CommentsTable. null).postResource(processorCallback. if (method.serviceHelperC allback). /* * (2) Insert-Update the ContentProvider status. } return. parameters). bundleOriginalIntent(requestIntent)). String mPictureId = params. bundleOriginalIntent(requestIntent)).mPictureId). parameters).getStatusCode().execute(). } } The processor will now make a call to the RESTMethod to actually make the callout to the server. // and performs the HTTP operation.equalsIgnoreCase(METHOD_GET)) { processor.send(result. RestMethod<Comments> method = new GetCommentsRestMethod(mContext.PICTURE_ID). } ResourceProcessorCallback processorCallback = makeProcessorCallback(requestIntent.getResource(processorCallback. RestMethodResult<Comments> result = method. // (3) Operation complete callback to Service callback. The processor will then add the data to the database including the state of the resource.send(REQUEST_INVALID. } 6 .

Building a REST Android Client Application | Craig Isakson The actual code in the processor is a simple REST callout to whichever API is being used. It would also be excessive to save each result to the database. does not mean that the application is following best practices. By using this design pattern. One such use case would be if the REST callout was being performed in an auto complete text box. Android as a whole would benefit. This allows the activity to update data to the user whether it be a success message or some sort of error that may have occurred. There is no need to worry if the callout errors because this is just performing get methods. Just because an application performs well most of the time. The design pattern described here functions very well and takes into account a number of different use cases that are often overlooked. This will let all the activities know that the call is finished and there is a result. such as cursor adapters. In this case. the application would have to make quite a few callouts while the user is typing. While this design pattern is great for most cases. as they are received from the REST callback. After the result has been passed. The processor will let the service know that it is done and what the result is. Then the service will implement the binder callback that it was sent via the intent from the service helper. the processor will update the content provider. which allows any listeners of the content provider the ability to update their information. 7 . there are a few different use cases where this type of pattern may not be ideal. If all developers applied the same concepts. the user will be presented with a much better experience.

android. 2012. Available at http://developer. Accessed April 19th. Access April 19th. 2012.com/ watch?v=xHXn3Kg2IQE. public class Intent. Available at https://github.Building a REST Android Client Application | Craig Isakson References Google I/O 2010 – Android REST client applications. 2012. 2012. Available at http://developer.com/aug-mn/restful-android.youtube. 8 .com/reference/android/app/Service.html. 2010. 2012. public abstract class Service. restful-android.android. Accessed April 19th. 2012. 2012.com/reference/android/content/Intent. Accessed April 19th.html. Available at http://www.