Android service, aidl - day 1

5,403 views

Published on

Published in: Technology

Android service, aidl - day 1

  1. 1. Android Background Processing – Servicesand IPC
  2. 2. Android ServicesA Service is an application component that can perform long-running operations in the background and does notprovide a user interface.A service can essentially take two forms:Started : A service is "started" when an application component (such as an activity) starts it by calling startService().Once started, a service can run in the background indefinitely, even if the component that started it is destroyed.Usually, a started service performs a single operation and does not return a result to the caller. For example, itmight download or upload a file over the networkBound : A service is "bound" when an application component binds to it by calling bindService(). A bound serviceoffers a client-server interface that allows components to interact with the service, send requests, get results, andeven do so across processes with interprocess communication (IPC). A bound service runs only as long as anotherapplication component is bound to it. Multiple components can bind to the service at once, but when all of themunbind, the service is destroyed.
  3. 3. Android Services – The BasicsTo create a service, you must create a subclass of Service (or one of its existing subclasses). In your implementation, youneed to override some callback methodsThe most important callback methods you should override are:onStartCommand() : The system calls this method when another component, such as an activity, requests that theservice be started, by calling startService(). Once this method executes, the service is started and can run in thebackground indefinitely. If you implement this, it is your responsibility to stop the service when its work is done,onBind() : The system calls this method when another component wants to bind with the service (such as to performRPC), by calling bindService(). In your implementation of this method, you must provide an interface that clients use tocommunicate with the service, by returning an IBinder.onCreate() : The system calls this method when the service is first created, to perform one-time setup procedures(before it calls either onStartCommand() or onBind()). If the service is already running, this method is not called.onDestroy() : The system calls this method when the service is no longer used and is being destroyed. Your serviceshould implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last callthe service receives.
  4. 4. Service Life Cycle
  5. 5. Started ServiceA started service is one that another component starts by calling startService(), resulting in a call to the servicesonStartCommand() method.When a service is started, it has a lifecycle thats independent of the component that started it and the service can run inthe background indefinitely, even if the component that started it is destroyed. As such, the service should stop itselfwhen its job is done by calling stopSelf(), or another component can stop it by calling stopService().Traditionally, there are two classes you can extend to create a started service:Service : This is the base class for all services. When you extend this class, its important that you create a new thread inwhich to do all the services work, because the service uses your applications main thread, by default, which could slowthe performance of any activity your application is running.IntentService : This is a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is thebest option if you dont require that your service handle multiple requests simultaneously. All you need to do isimplement onHandleIntent(), which receives the intent for each start request so you can do the background work.
  6. 6. Most started services dont need to handle multiple requests simultaneously (which can actually be a dangerousmulti-threading scenario), its probably best if you implement your service using the IntentService class.The IntentService does the following:1. Creates a default worker thread that executes all intents delivered to onStartCommand() separate from yourapplications main thread.2. Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you neverhave to worry about multi-threading.3. Stops the service after all start requests have been handled, so you never have to call stopSelf().4. Provides default implementation of onBind() that returns null.5. Provides a default implementation of onStartCommand() that sends the intent to the work queue and then toyour onHandleIntent() implementation.Intent Services
  7. 7. public class HelloIntentService extends IntentService {/*** A constructor is required, and must call the super IntentService(String)* constructor with a name for the worker thread.*/public HelloIntentService() {super("HelloIntentService");}/*** The IntentService calls this method from the default worker thread with* the intent that started the service. When this method returns, IntentService* stops the service, as appropriate.*/@Overrideprotected void onHandleIntent(Intent intent) {// Normally we would do some work here, like download a file.// For our sample, we just sleep for 5 seconds.long endTime = System.currentTimeMillis() + 5*1000;while (System.currentTimeMillis() < endTime) {synchronized (this) {try {wait(endTime - System.currentTimeMillis());} catch (Exception e) {}}}}}Structure of an IntentService
  8. 8. Service OperationsStart a ServiceYou can start a service from an activity or other application component by passing an Intent (specifying the service tostart) to startService(). The Android system calls the services onStartCommand() method and passes it the Intent.Intent intent = new Intent(this, HelloService.class);startService(intent);Stop a ServiceA started service must manage its own lifecycle. That is, the system does not stop or destroy the service unless itmust recover system memory and the service continues to run after onStartCommand() returns. So, the servicemust stop itself by calling stopSelf() or another component can stop it by calling stopService().Once requested to stop with stopSelf() or stopService(), the system destroys the service as soon as possible.
  9. 9. Running a Service in ForegroundA foreground service is a service thats considered to be something the user is actively aware of and thus not acandidate for the system to kill when low on memory. A foreground service must provide a notification for the statusbar, which is placed under the "Ongoing" heading, which means that the notification cannot be dismissed unless theservice is either stopped or removed from the foreground.To request that your service run in the foreground, call startForeground(). This method takes two parameters: an integerthat uniquely identifies the notification and the Notification for the status bar. For example:Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),System.currentTimeMillis());Intent notificationIntent = new Intent(this, ExampleActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);notification.setLatestEventInfo(this, getText(R.string.notification_title),getText(R.string.notification_message), pendingIntent);startForeground(ONGOING_NOTIFICATION, notification);
  10. 10. Bound ServicesA bound service allows components (such as activities) to bind to the service, send requests, receive responses, andeven perform interprocess communication (IPC). A bound service typically lives only while it serves another applicationcomponent and does not run in the background indefinitely.To provide binding for a service, you must implement the onBind() callback method. This method returns an IBinderobject that defines the programming interface that clients can use to interact with the service.A client can bind to the service by calling bindService(). When it does, it must provide an implementation ofServiceConnection, which monitors the connection with the service. The bindService() method returns immediatelywithout a value, but when the Android system creates the connection between the client and service, it callsonServiceConnected() on the ServiceConnection, to deliver the IBinder that the client can use to communicate with theservice.
  11. 11. Creating a Bind ServiceWhen creating a service that provides binding, you must provide an IBinder that provides the programming interfacethat clients can use to interact with the service. There are three ways you can define the interface:Extending the Binder class : If your service is private to your own application and runs in the same process as theclient (which is common), you should create your interface by extending the Binder class and returning an instance ofit from onBind().Using a Messenger : If you need your interface to work across different processes, you can create an interface for theservice with a Messenger. In this manner, the service defines a Handler that responds to different types of Messageobjects.Using AIDL : AIDL (Android Interface Definition Language) performs all the work to decompose objects into primitivesthat the operating system can understand and marshall them across processes to perform IPC. The previoustechnique, using a Messenger, is actually based on AIDL as its underlying structure.
  12. 12. Extending Binder ClassIf your service is used only by the local application and does not need to work across processes, then you canimplement your own Binder class that provides your client direct access to public methods in the service.Heres how to set it up:1. In your service, create an instance of Binder that either:1. contains public methods that the client can call2. returns the current Service instance, which has public methods the client can call3. or, returns an instance of another class hosted by the service with public methods the client can call2. Return this instance of Binder from the onBind() callback method.3. In the client, receive the Binder from the onServiceConnected() callback method and make calls to the boundservice using the methods provided.
  13. 13. Using a MessengerIf you need your service to communicate with remote processes, then you can use a Messenger to provide theinterface for your service. This technique allows you to perform interprocess communication (IPC) without the need touse AIDL.Heres a summary of how to use a Messenger:1. The service implements a Handler that receives a callback for each call from a client.2. The Handler is used to create a Messenger object (which is a reference to the Handler).3. The Messenger creates an IBinder that the service returns to clients from onBind().4. Clients use the IBinder to instantiate the Messenger (that references the services Handler), which the client usesto send Message objects to the service.5. The service receives each Message in its Handler—specifically, in the handleMessage() method.
  14. 14. AIDL – Android Interface Definition LanguageAIDL (Android Interface Definition Language) allows you to define the programming interface that both theclient and service agree upon in order to communicate with each other using interprocess communication(IPC).On Android, one process cannot normally access the memory of another process. So to talk, they need todecompose their objects into primitives that the operating system can understand, and marshall the objectsacross that boundary for you.
  15. 15. Steps in implementing AIDL in your programYou must define your AIDL interface in an .aidl file using the Java programming language syntax, then save itin the source code (in the src/ directory) of both the application hosting the service and any otherapplication that binds to the service.When you build each application that contains the .aidl file, the Android SDK tools generate an IBinderinterface based on the .aidl file and save it in the projects gen/ directory. The service must implement theIBinder interface as appropriate. The client applications can then bind to the service and call methods fromthe IBinder to perform IPC.To create a bounded service using AIDL, follow these steps:1. Create the .aidl file : This file defines the programming interface with method signatures.2. Implement the interface : The Android SDK tools generate an interface in the Java programminglanguage, based on your .aidl file. This interface has an inner abstract class named Stub that extendsBinder and implements methods from your AIDL interface. You must extend the Stub class andimplement the methods.3. Expose the interface to clients : Implement a Service and override onBind() to return yourimplementation of the Stub class.
  16. 16. 1. Creating a .aidl file// IRemoteService.aidlpackage com.example.android;// Declare any non-default types here with import statements/** Example service interface */interface IRemoteService {/** Request the process ID of this service, to do evil things with it. */int getPid();/** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);}Create a file with .aidl extention into the project/src folder. Write the file in above shown manner.
  17. 17. 2. Implementing the interface in Service classWhen you build your application, the Android SDK tools generate a .java interface file named after your .aidlfile. The generated interface includes a subclass named Stub that is an abstract implementation of its parentinterface (for example, YourInterface.Stub) and declares all the methods from the .aidl file.private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {public int getPid(){return Process.myPid();}public void basicTypes(int anInt, long aLong, boolean aBoolean,float aFloat, double aDouble, String aString) {// Does nothing}};
  18. 18. 3. Exposing your interface to your clientsOnce youve implemented the interface for your service, you need to expose it to clients so they can bind to it.To expose the interface for your service, extend Service and implement onBind() to return an instance of yourclass that implements the generated Stub (as discussed in the previous section). Heres an example service thatexposes the IRemoteService example interface to clients.public class RemoteService extends Service {@Overridepublic void onCreate() {super.onCreate();}@Overridepublic IBinder onBind(Intent intent) {// Return the interfacereturn mBinder;}private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {public int getPid(){return Process.myPid();}public void basicTypes(int anInt, long aLong, boolean aBoolean,float aFloat, double aDouble, String aString) {// Does nothing}};}

×