Lecture Series on Android Programming Lecturer: Prof.Luqun Li ([email protected]) Teaching Assistants: Fengyou Sun, Haijun Yang, Ting Sun Chapter 8 Building and Consuming Services
Dec 22, 2015
Lecture Series on Android Programming
Lecturer: Prof.Luqun Li ([email protected])Teaching Assistants: Fengyou Sun, Haijun Yang, Ting Sun
Chapter 8 Building and Consuming
Services
Shanghai Normal University2
Contents
11 HTTP Services
22 Android Services
Shanghai Normal University3
Consuming HTTP Services
Android applications pull information from various sourcesA common integration strategy is to use HTTPThe Apache HttpClient is a comprehensive HTTP client, HTTP GET and POST
Shanghai Normal University4
HttpClient for HTTP GET Requests
Pattern for using HttpClient: 1. Create an HttpClient (or get an existing reference).
2. Instantiate a new HTTP method, such as PostMethod or GetMethod .
3. Set HTTP parameter names/values.
4. Execute the HTTP call using the HttpClient.
5. Process the HTTP response.HttpGetDemo.java
Shanghai Normal University5
Limitations of HttpGet
Pass name/value parameters as part of the request by appending name/value pairs to the URL:
HttpGet request = new HttpGet("http://somehost/WS2/Upload.aspx?one=valueGoesHere");
client.execute(request);
Length of a URL should be kept below 2,048 characters,use HTTP POST instead.
Shanghai Normal University6
HttpClient for HTTP POST Requests
Making an HTTP POST call is very similar to making an HTTP GET call.
HttpPostDemo
Shanghai Normal University7
Multipart Example
To do multipart POST calls, you need to get three additional Apache open source projects: Apache Commons IO, Mime4j, and HttpMime.
Commons IO:http://commons.apache.org/io/
Mime4j: http://james.apache.org/mime4j/
HttpMime: http://hc.apache.org/downloads.cgi (inside of HttpClient)
TestMultipartPost
Shanghai Normal University8
Dealing with Exceptions
transport exceptionsdetecting transport issues and retrying requests by HttpClient
protocol exceptionsflushed out during development
Timeoutsyou’ll have to deal with
Shanghai Normal University9
Effective approach
A simple and effective approach to dealing with both types of timeouts—connection timeouts and socket timeouts—is to wrap the execute() method of your HTTP request with a try / catch and then retry if a failure occurs.
code
Shanghai Normal University10
Addressing Multithreading Issues
Create one HttpClient for the entire application and all HTTP communicationPay attention to multithreading issues when making simultaneous requests through the same HttpClientHttpClient provides facilities that make this easy—create the DefaultHttpClient using a ThreadSafeClientConnManager
Shanghai Normal University11
Singleton pattern
A singleton class to service all your HTTP requests with only one HttpClient ClientConnectionManager responsible for managing HTTP connections for the HttpClientThreadSafeClientConnManager to avoid overlap
CustomHttpClient.java
HttpActivity.java
Shanghai Normal University12
Contents
11 HTTP Services
22 Android Services
Shanghai Normal University13
Android Services
Android supports two types of services:
Local services, simply support the application that is hosting the service
Remote services, accessible from other applications on the device, defined to clients using Android Interface Definition Language (AIDL).
Shanghai Normal University14
Understanding Local Services
Started via Context.startService()Stoped viaContext.stopService() or called stopSelf() by itself
Note that when Context.startService() is called and the service has not already been created, the system will instantiate the service and call the service’s onStartCommand() method.
BackgroundService.java
Shanghai Normal University15
Status Notifications
To create a notification, you must use two classes: Notification and NotificationManager.
Notification, to define the properties of your status notification NotificationManager, an Android system service that executes and manages all status notifications getSystemService() , to retrieve a reference to the NotificationManager notify() , to notify the user
Shanghai Normal University16
To create a status notification
1. Get a reference to the NotificationManager:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Shanghai Normal University17
To create a status notification
2.Instantiate the Notification:
int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
Shanghai Normal University18
To create a status notification
3.Define the notification's message and PendingIntent:
Context context = getApplicationContext(); CharSequence contentTitle = "My notification"; CharSequence contentText = "Hello World!"; Intent notificationIntent = new Intent(this, MyClass.class); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
Shanghai Normal University19
To create a status notification
4.Pass the Notification to the NotificationManager: private static final int HELLO_ID = 1; mNotificationManager.notify(HELLO_ID, notification);
Shanghai Normal University20
Understanding AIDL Services
To build a service via remote procedure call (RPC)An interface definition language (IDL) to define the interface that will be exposed to clientsAndroid Interface Definition Language (AIDL)
Shanghai Normal University21
To build a remote service
1. Write an AIDL file that defines your interface to clients. The AIDL file uses Java syntax and has an .aidl extension. Use the same package name inside your AIDL file as t he package for your Android project. 2. Add the AIDL file to your Eclipse project under the src directory. The Android Eclipse plug-in will call t he AIDL compiler to generate a Java interface from the AIDL file (the AIDL compiler is called as part of the build process). 3. Implement a service, and re turn the interface from the onBind() method. 4. Add the service configuration to your AndroidManifest.xml file.
Shanghai Normal University22
Defining a Service Interface in AIDL
package com.androidbook.services.stockquoteservice; interface IStockQuoteService { double getQuote(String ticker); }
When you create the AIDL file, the Android Eclipse plug-in runs the AIDL compiler to process your AIDL fileThe compiler generates a Java interface suitable for RPC communication in your AIDL file— com.androidbook.services.stockquoteservice
Shanghai Normal University23
Generated classes
The interface we defined in the AIDL file is implemented as an interface in the generated code (that is, there is an interface named IStockQuoteService). A static final abstract class named Stub extends android.os.Binder and implements IStockQuoteService. Note that the class is an abstract class. An inner class named Proxy implements the IStockQuoteService that proxies the Stub class. The AIDL file must reside in the package where the generated files are supposed to be (as specified in the AIDL file’s package declaration).
generated
Shanghai Normal University24
Implementing an AIDL Interface
The inner class Extending the Stub class called StockQuoteServiceImpl
Serving as the remote-service implementation
Returned from the onBind() method
A service declaration in the AndroidManifest.xml file
IStockQuoteService
manifest
Shanghai Normal University25
Calling Service from a Client
Copy the AIDL file from the service project to the client’sThe AIDL file serves as a contract between the client and the service
Shanghai Normal University26
ServiceConnection
private ServiceConnection serConn = new ServiceConnection() {
@Override public void onServiceConnected(ComponentName name, IBinder service) { Log.v(TAG, "onServiceConnected() called"); stockService = IStockQuoteService.Stub.asInterface(service); callService(); }
@Override public void onServiceDisconnected(ComponentName name) { Log.v(TAG, "onServiceDisconnected() called"); stockService = null; } };
client
Shanghai Normal University27
ServiceConnection
When we call the bindService() method, we pass in the reference to this member. When the connection to the service is established, the onServiceConnected() callback is invoked, and we then obtain a reference to the IStockQuoteService using the Stub and enable the Call Service button.
Shanghai Normal University28
ServiceConnection
Please notice the onServiceDisconnected() callback. This does not get invoked when we unbind from the service. It is only invoked if the service crashes. If it does, we should not think that we’re still connected, and we might need to reinvoke the bindService() call.
Shanghai Normal University29
Local service versus an AIDL service
A local service does not support onBind(), returning null Accessible only to the components of the host application You call local services by calling startService().
Shanghai Normal University30
Local service versus an AIDL service
The service implements the AIDL contract, and clients bind to the AIDL definition. The service implements the contract by returning an implementation of the AIDL interface from the onBind() method. Clients bind to an AIDL service by calling bindService() , and they disconnect from the service by calling unbindService() .
Shanghai Normal University31
Passing Complex Types to Services
AIDL’s support for nonprimitive types: AIDL supports String and CharSequence. AIDL allows you to pass other AIDL interfaces, but you need to have an import statement for each AIDL interface you reference (even if the referenced AIDL interface is in the same package). AIDL allows you to pass complex types that implement the android.os.Parcelable interface. You need to have an import statement in your AIDL file for these types. AIDL supports java.util.List and java.util.Map , with a few restrictions. The allowable data type s for the items in the collection include Java primitive, String, CharSequence, and android.os.Parcelable . You do not need import statements for List or Map , but you do need them for the Parcelables. Nonprimitive types, other than String, require a direct ional indicator. Directional indicators include in, out , and inout . in means the value is set by the client; out means the value is set by the service; and inout means both the client and service set the value.
Shanghai Normal University32
Directional indicator
Nonprimitive types, other than String, require a directional indicator. Directional indicators include in, out , and inout . in means the value is set by the client; out means the value is set by the service; and inout means both the client and service set the value.
Shanghai Normal University33
Parcelable
1. Implement the Parcelable interface. implement writeToParcel() and readFromParcel(). Note that the order in which you write properties must be the same as the order in which you read them.
2. Add a static final property to the class with the name CREATOR .
The property needs to implement the android.os.Parcelable.Creator<T> interface.
3. Provide a constructor for the Parcelable that knows how to create the object from the Parcel. 4. Define a Parcelable class in an .aidl file that matches the .java file containing the complex type .
The AIDL compiler will look for this file when compiling your AIDL files.
Shanghai Normal University34
Implementing the Parcelable Interface
Person.java
Person.aidl package com.androidbook.services.stock2;
parcelable Person;
Person.java
Shanghai Normal University35
Passing Parcelables to Services
package com.androidbook.services.stock2; import com.androidbook.services.stock2.Person; interface IStockQuoteService { String getQuote(in String ticker,in Person requester); }
Note that we have directional indicators on the parameters because the parameters include nonprimitive types and that we have an import statement for the Person class.
Shanghai Normal University36
Service implementation
StockQuoteService2.java
StockQuoteService2 Layout
AndroidManifest.xml
code
layout
manifest
Shanghai Normal University37
To implement a client
Copy the Person.java and Person.aidl files to the client project modify main.xml and MainActivity.java
Shanghai Normal University38
Summary
We talked about consuming external HTTP services using the Apache HttpClient. With regard to using the HttpClient, we showed you how to do HTTP GET calls and HTTP POST calls. We also showed you how to do multipart POSTs.We then moved on to the formal Android Services topics.
Shanghai Normal University39
Interview Questions
1. Why is it bad practice to call a web service from the main UI thread? 2. Can you bind to a local service?3. What is one reason for giving a notification to the NotificationManager from a service? 4. What are ThreadGroups good for? 5. Can a Parcelable be used to send data to an activity? Why or why not?