How to use Android Service: Tutorial
Android Service
Android IntentService
Android Broadcast receiver and Service
Android Service Overview
We already know that Android Activity can be started, stopped, destroyed if the system resources become too low and maybe can be recreated, a Service are designed to have a longer life. A Service in Android can be started from an Activity, from a Broadcast receiver and other services too.We have to notice that using Service we don’t create automatically new threads, so if we implement a simple logic inside our Service, that doesn’t require long time processing we don’t need to run it a separate thread, but if we have to implement complex logic, with long time processing, we have to take care of creating a new thread, otherwise the service runs on the main thread and it could cause ANR problem.
In Android a Service is used for two main reason:
- Implement multi-task
- Enable Inter-Process-Communication (IPC)
In the second case, we want to “share” some common functions so that different app can re-use them. For example, we can suppose we have a service that sends an email and we want to share this service among several apps so that we don’t have to rewrite the same code. In this case we can use IPC so that the service exposes a “remote” interface that can be called by other app.
In this post, we cover the first case, in this case we have a local service, local means that the service can be seen just inside our apk.
Getting started with Android Service
Now we know more about Service, we want to create it. In Android to create a Service we have to extend Service class.public class TestService extends Service {As we can see, we have to implement only one method called onBind. In our case, we are using local service, so this method should return null. As we mentioned before, a Service has its lifecycle and we can override some callback methods so that we can handle its different states:
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
public class TestService extends Service {The first method onCreate is called only one time when the Service has to created. If the Service is already running this method won’t be called. We don’t call it directly but it is the OS that calls it.
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
OnStartCommand is the most important method because it is called when we required to start the Service. In this method we have the Intent passed at time we run the Service, in this way we can exchange some information with the Service. In this method, we implement our logic that can be execute directly inside this method if it isn’t time expensive otherwise we can create a thread. As you can see this method requires we return an Integer as result. This integer represents how the Service should be handled by the OS:
- START_STICKY : Using this return value, if the OS kills our Service it will recreate it but the Intent that was sent to the Service isn’t redelivered. In this way the Service is always running
- START_NOT_STICKY: If the SO kills the Service it won’t recreate it until the client calls explicitly onStart command
- START_REDELIVER_INTENT: It is similar to the START_STICKY and in this case the Intent will be redelivered to the service.
OnDestroy is the method called by the OS when the Service will be destroyed.
Once we have our service class, we have to declare it in the Manifest.xml so that we can use it:
<service android:name=".TestService"
android:enabled="true"/>
Start and Stop Service in Android
As we know a Service has to be started and eventually stopped so that it can accomplish its task. We can suppose to start it from an activity and we could pass to the service some information using Intent. We can suppose that our Activity has two buttons one to start and one to stop the Service:btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, TestService.class);
i.putExtra("name", "SurvivingwithAndroid");
MainActivity.this.startService(i);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, TestService.class);
MainActivity.this.stopService(i);
}
});
In the code above at line 5, we create an Intent passing the class name that handles our Service, moreover we set some params like name and then we start the Service at line 7. In the same way, at line 17 we stop the service.
Clicking on Start button we get in the Log:
We can notice that the
onCreate
method is called because it is the first time we start the service, if we click again on start button the OS doesn’t call onCreate method. When we click on stop button the OS destroy the service.Android IntentService
As we mentioned before a service runs on the main thread, so we have to be very careful when we implement some logic in this service. We have to consider that if this logic is a blocking operation or it requires long time to finish a ANR problem could occur. In this case we have to move our logic to a separate thread, meaning we have to create a thread in onStartCommand method and run it.There is another class called IntentService derived from Service that simplify our life. This class is useful when we don’t need to handle multiple requests at the same time. This class creates a worker thread to handle different requests. This class performs this operation:
- create a separate thread to handle the request
- create a request queue and pass one Intent at time
- create a default implementation of onStartCommand
- stop the service when all the requests are processed
public class TestIntentService extends IntentService {In this case we have only one method to implement called
public TestIntentService() {
super("TestIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
}
}
onHandleIntent
. Here we implement out logic without caring if this is operation requires long time or not, because this method is called in a separate thread.Starting service automatically
Many times we want to start our service automatically, for example at boot time. We know to start a Service we need a component to start it. How can we do it? Well, we could use a Broadcast receiver that starts our service. If for example we want to start it at the smartphone boot time, we create first a Broadcast receiver that listens to this event and then it starts the service.public class BootBroadcast extends BroadcastReceiver {and in the Manifest.xml
@Override
public void onReceive(Context ctx, Intent intent) {
ctx.startService(new Intent(ctx, TestService.class));
}
}
<receiver android:name=".BootBroadcast">
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
0 comments:
Post a Comment