Question

i have an IntentService that should act like a manager and create Tasks in a queue (Runnable) that are submitted to a ThreadPool.

Im a little bit confused of the lifecycle of an IntentService:

The method protected abstract void onHandleIntent (Intent intent) runs already on a separated Thread. In the onHandleIntent I would create a new Runnable instance and submit it to the ThreadPool. My Service looks like this:

    public class SyncService extends IntentService {

    private final ThreadPoolExecutor threadPool;

    public SyncService() {
        super("SyncService");
        BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
        threadPool = new ThreadPoolExecutor(1, 1, 20, TimeUnit.SECONDS, queue);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getInstance().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getInstance().unregister(this);
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent.getAction().equals("sync")){
            threadPool.submit(new SyncRunnable());
        }else 
            if(intent.getAction().equals("delete")){
            threadPool.submit(new DeleteRunnable());
        } else 
            if(intent.getAction().equals("register")){
            threadPool.submit(new RegisterRunnable())
        }

    }
}

My questions:

  1. Is it a good idea to use a ThreadPool in a IntentService?
  2. If I use a ThreadPool, than the IntentService will be destroyed if the Threadpool has no more Runnables to execute or queued, right?
  3. Is IntentService already something that I want to achieve and should I simply execute my (long running) Runnable code in the onHandleIntent() because this method alread runs on the IntentService worker Thread? If yes, is there a queue limit for intent, since onHandleIntent() could run up to 30 seconds before finishing and handling the next Intent.
Was it helpful?

Solution

Is it a good idea to use a ThreadPool in a IntentService?

Not really. IntentService is already a single threaded (serial) variant of what you try to achieve. I would derive directly from Service.

If I use a ThreadPool, than the IntentService will be destroyed if the Threadpool has no more Runnables to execute or queued, right?

No. IntentService can go into the destroyed state once you return from onHandleIntent - i.e. immediately because threadPool.submit is non-blocking. Within the source it calls stopSelf(int) with the startId it got when the service was started.

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1);
    }
}

A Service will go into destroyed state if you call stopSelf with the latest (highest) startId. It will keep running if a newer start is in the queue.

If the service goes into destroyed state it will not kill your thread pool because it has no knowledge about it. The problem is that Android now thinks that your service is dead and it will no longer count as a reason to keep your app process. The service running vs destroyed state is essentially just a way to tell Android that there is something going on and you don't want to get destroyed.

If you want to do it the right way you have to keep the service state in sync with what is actually going on.

Is IntentService already something that I want to achieve and should I simply execute my (long running) Runnable code in the onHandleIntent() because this method alread runs on the IntentService worker Thread?

If you are happy with single threaded serial execution yes. That's what onHandleIntent does for you.

If yes, is there a queue limit for intent, since onHandleIntent() could run up to 30 seconds before finishing and handling the next Intent.

There is no limit (it's a linked list as far as I can tell). But there is also nothing that stops you from producing more tasks than it can handle which will ultimately lead to some kind of overflow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top