DrHowdyDoo
DrHowdyDoo

Reputation: 2807

How to wait for multiple threads to finish without blocking ui in android?

I am executing tasks parallelly on threads using threadPoolExecuter and i want to wait for all the tasks to complete without blocking the main ui. I don't want to use async task here. and methods like service.awaitTermination() is blocking the main ui.I have checked similar questions but didn't find answer to my particular problem. I am using a for loop to pass runnables to threads like this :

for (ApplicationInfo info : applicationInfoList) {
        service.execute(new MyTask(info));
    }

MyTask() function execute the same opertaion for all the ApplicationInfo type objects here. Please help.....

Upvotes: 3

Views: 1546

Answers (1)

Yurii Tsap
Yurii Tsap

Reputation: 3744

Well, I can see you are using java, so probably you aren't allowed for some reason to use coroutines. With coroutines, it would be easier to achieve such a result. Consider using them, especially have a look at their way to solve your problem.

What I would use in your case is - CountDownLatch.

Your code will look similar to this one:

CountDownLatch latch = new CountDownLatch(applicationInfoList.size);
            for (ApplicationInfo info : applicationInfoList) {
                service.execute(new MyTask(info, latch));
            }
            latch.await();

MyTask under the hood should call latch.countDown() when your work is done.

latch.await() throws InterruptedException so it should be handled.

Note: Anyway, it blocks the thread you are currently on. The easiest way would be to migrate this logic to Runnable and provide a callback:

class YourButchTask implements Runnable {
            
            private WorkDoneCallback callback;

            public YourButchTask(WorkDoneCallback callback) {
                this.callback = callback;
            }

            @Override
            public void run() {
                CountDownLatch latch = new CountDownLatch(applicationInfoList.size);
                for (ApplicationInfo info : applicationInfoList) {
                    service.execute(new MyTask(info, latch));
                }
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //handle it
                }
                callback.workWasDone();
            }
        }

Afterward, you can submit your task to your service. Note: your callback will be invoked from the executor thread, so you aren't allowed to access UI from it.

Here is a nice and simple tutorial, hopefully, that will help.

Update:

To be clear - Callback is your custom interface that will notify you when the work is done. Go ahead and use SAM, example:

interface WorkDoneCallback{
    void workWasDone();
}

P.S. To redirect calls on main thread just use Handler with mainLooper under the hood, or runOnUiThread().

Upvotes: 2

Related Questions