Android : ExecutorService Fanboy for Service
Before going through this article I will request you guys to go through my previous articles which is About Service with Handler Thread.
If you have been through my last post then you know now that how much its useful to use thread with Service. And also IntentService is sometime become a life saviour in point of User experience of app. But with the IntentService the problem is only one task is executed at a particular time which is handled by the Handler class internally, What if have a situation in which we have to execute multiple task in service at the same time. In such cases we can use ExecutorService with our application. ExecutorSerivce maintains the thread pool for the running services in Android.
Executor is API provided by Android, which contains all the required methods to create ExecutorService. This implementation helps us to execute multiple long running task as soon as possible. You have to make ensure that your service is Alive by using startForground() and stopForground() because Android don’t care about your service and can kill your long running service if the system resources is not good enough for other functions. Service also don’t stack these two methods in the system and developer had to maintain its functionality by maintaining a counter of active jobs, and when there is no job to perform you can call stopForeground() to stop the service. Following is the Implementation of the Service which can perform multiple task at the same time. No System resources will be used when the service is not performing any task and also it will automatically cache the thread to minimise the creation of thread again and again.
public class ServiceWithExecutorClass extends Service {// Intent action that is declared to perform task.
public static final String ACTION_TO_PEFROM_ON_MEDIA = “action.of.media.to.complete”;// Outpufile type key of extras in Intent
public static final String EXECUTOR_OUTPUT_TYPE = “output_type”;// Notification Unique id to identify created Notification from //service
private static final int NOTIFICATION = 1001;private final Object mloack = new Object();private ExecutorService mExecutorService;// No of running jobs
private int runningJobs = 0;// To know either the Service is running in forground or not
private boolean isForground = false;@Nullable
@Override
public IBinder onBind(Intent intent) {// Returns null which indicate that Service is not Binded with any //component of Android
return null;
}@Override
public void onCreate() {
super.onCreate();// Creating Cached thread pool so that avoid creation of Thread //again and again
mExecutorService = Executors.newCachedThreadPool(); }@Override
public int onStartCommand(Intent intent, int flags, int startId) { String actionName = intent.getAction();// Comparing the action given to the Service
if (actionName.equals(ACTION_TO_PEFROM_ON_MEDIA)) { String outputType = intent.getStringExtra(EXECUTOR_OUTPUT_TYPE);// Strated the new task and increased the no. of Jobs being executed
synchronized (mloack) { ActionNeedToPerfomInThread actionPerForm = new ActionNeedToPerfomInThread(intent.getData(), outputType); mExecutorService.execute(actionPerForm); runningJobs++; startForGroudnIfneeded();
}
}// Service will not start again if System restart itself again
return START_NOT_STICKY;}// Method to start the service in forground if the no. of jobs is //larger
private void startForGroudnIfneeded() { if (!isForground) {
Notification notification = builNotification();
startForeground(NOTIFICATION, notification);
isForground = true; }
}// method to return Notification
private Notification builNotification() {// Implement the creation of Notification here.
return null;
}// method to stop Service if all the job i done
private void stopForegroundIfAllDone() { if (runningJobs == 0 && isForground) { stopForeground(true);
isForground = false; } }// Shutdown the excutor Serivce if the Serivice is bing killled or stoped in for some serivce
@Override
public void onDestroy() {
super.onDestroy();
mExecutorService.shutdownNow();
synchronized (mloack) {
runningJobs = 0;
stopForegroundIfAllDone();
}
}// Runnable method to implement the actual task which need to //perform in every call of new Job
private class ActionNeedToPerfomInThread implements Runnable {private Uri uri;
private String outputType;private ActionNeedToPerfomInThread(Uri uriData, String ouputType) { this.outputType = ouputType;
this.uri = uriData;
}@Override
public void run() { synchronized (mloack) { // After completing job reduce the no. of jobs that is being //executed in the ExecutorService
runningJobs — ;
stopForegroundIfAllDone();
}
}
}}

