Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IntentService and Threadpool

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.
like image 308
sockeqwe Avatar asked Dec 05 '13 14:12

sockeqwe


People also ask

Why IntentService is deprecated?

This class was deprecated in API level 30. IntentService is subject to all the background execution limits imposed with Android 8.0 (API level 26). Consider using WorkManager or JobIntentService , which uses jobs instead of services when running on Android 8.0 or higher.

Does IntentService run on background thread?

The Service runs in background but it runs on the Main Thread of the application. The IntentService runs on a separate worker thread.

What is the difference between services and thread in android?

Service : is a component of android which performs long running operation in background, mostly with out having UI. Thread : is a O.S level feature that allow you to do some operation in the background.

How to stop thread service in android?

You call onDestroy() method for stop service.


1 Answers

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.

like image 120
zapl Avatar answered Sep 30 '22 06:09

zapl