Basics of Android : Part III – Android Services
Many a times the application needs to do some tasks in the background for which user interventions is not required (or very less intervention is required). These background processes keeps working even if user is using some other application on the phone.
To define such background processes android has a concept of Services. Service in android is long lived application component. Service doesn’t implement any User Interface. Common example of service is Media Player application that keeps playing song in the background, file download application that can download the file in the background.
Let’s see how to create a service.
Creating a service
Android has defined a base class for all services as ‘Service’. All the services have to extend from this Service class. Service class defines service lifecycle methods like onCreate(), onStart(), onDestroy(). Here is the example a service class
package com.wissen.testApp.service;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
}
}
The above service is notifying the user when the service is created and service is destroyed.
Like every thing else in android, Service in android are also associated with the intents. This intent is required while using the service.
The service entry has to be done in the AndroidManifest.xml file along with the service intent as shown below:
<service class=".service.MyService"> <intent-filter> <action android:value="com.wissen.testApp.service.MY_SERVICE" /> </intent-filter> </service>
Now our service is created and can be used by the application code.
Using the service:
The application can start the service with the help of Context.startService method. The method will call the onCreate method of the service if service is not already created; else onStart method will be called. Here is the code to start the MyService
..
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.wissen.testApp.service.MY_SERVICE");
startService(serviceIntent);
The service started with startService method will keep on running until stopService() is called or stopSelf() method is called.
Another way to use service is to bind to the service. The service contented this way will be considered required by the system only for as long as the calling context exists. To bind to the service a service connection object need to be created. The service connection object tell the application when the service is connected or disconnected. Here is how you can bind to the service.
…
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("INFO", "Service bound ");
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.i("INFO", "Service Unbound ");
}
}
bindService(new Intent("com.wissen.testApp.service.MY_SERVICE"), conn, Context.BIND_AUTO_CREATE);
}
…
The application can communicate with the service when application is connected with the service. Generally the service communicate is done with the help of Service Interface. Service interface defines methods for which service can provider implementation. For example here is some interface:
package com.wissen.testApp;
public interface IMyService {
public int getStatusCode();
}
Using this interface the application can ask the Service about its status. Lets see how the service can support this interface. Previously we saw a method called onBind which return IBinder object, the method gets called when some client of the service binds to the service. This is the same object that is passed to the onServiceConnected method. The application can communicate with the service using this IBinder object. Here is how this can be done:
public class MyService extends Service {
private int statusCode;
private MyServiceBinder myServiceBinder = new MyServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return myServiceBinder; // object of the class that implements Service
// interface.
}
public class MyServiceBinder extends Binder implements IMyService {
public int getStatusCode() {
return statusCode;
}
}
// .......
}
And here is how application can call getStatusCode method:
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyService myService = (IMyService) service;
statusCode = myService.getStatusCode();
Log.i("INFO", "Service bound ");
}
// ........
};
You can also define ServiceListener interface which the client of the service has to be implemented to gets update from the service. In that case the service interface will have to define methods to register and unregister the ServiceListener objects.
Communication with Remote Service:
The services that we defined until now run in the application processes, you can define service that can run in their own process. For two processes to communicate with each other they need to marshal the object to sent to other process.
Android provide an AIDL tool (Android Interface definition Language) to handle all marshalling and communication part.
The service has to provide the Service interface as an aidl file. The AIDL tool will create a java interface corresponding for the aidl Service Interface. The AIDL tool also defines a stub class in the generated service interface, which implements the Service Interface (as abstract methods) and also provides some other required functionality. The service interface implementation class has to extend this stub class and define the service interface methods. The service onBind method will return object of this implementation class so that the client application can use the service methods. Here is the how the communication can be done:
Create a file as IMyRemoteService.aidl as follows:
package com.wissen.testApp;
interface IMyRemoteService {
int getStatusCode();
}
The eclipse android plug-in will create a Java interface for the aidl file created above as the part of build process.
The interface generated above will have a Stub inner class. Define a class that extends this stub class. Here is the code for the RemoteService class:
package com.wissen.testApp;
class RemoteService implements Service {
int statusCode;
@Override
public IBinder onBind(Intent arg0) {
return myRemoteServiceStub;
}
private IMyRemoteService.Stub myRemoteServiceStub = new IMyRemoteService.Stub() {
public int getStatusCode() throws RemoteException {
return 0;
}
};
// ........
}
When the client application connect to the service the onServiceConnected method will be called and client will get the IBinder object of the service. The Stub class also provides a method to obtain the Service Interface object from the IBinder object. Here is the client onServiceConnected code
…
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IMyRemoteService myRemoteService = IMyRemoteService.Stub
.asInterface(service);
try {
statusCode = myRemoteService.getStatusCode();
} catch (RemoteException e) {
// handle exception
}
Log.i("INFO", "Service bound ");
}
// .........
};
Permissions:
Service may specify required user permissions in the AndroidManifest.xml in <service> tag like this,
<service class=".service.MyService" android:permission="com.wissen.permission.MY_SERVICE_PERMISSION"> <intent-filter> <action android:value="com.wissen.testApp.service.MY_SERVICE" /> </intent-filter> </service>
Then to use above service the application has to ask for permission with the help of <user-permission> tag as follows:
<uses-permission android:name="com.wissen.permission.MY_SERVICE_PERMISSION"></uses-permission>
So in today’s post we saw how to create service and use it. In the next post we will see how to use ContentProviders.
Eigentlich bin ich ja nicht so der “Blog-Fan” aber nach deinem Artikel