首页 > 解决方案 > 如何等待多个线程完成而不阻塞android中的ui?

问题描述

我正在使用 threadPoolExecuter 在线程上并行执行任务,我想等待所有任务完成而不阻塞主 ui。我不想在这里使用异步任务。和 service.awaitTermination() 之类的方法阻止了主 ui。我检查了类似的问题,但没有找到我的特定问题的答案。我正在使用for循环将runnables传递给这样的线程:

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

MyTask() 函数对此处的所有 ApplicationInfo 类型对象执行相同的操作。请帮忙.....

标签: android

解决方案


好吧,我可以看到您正在使用 java,因此可能出于某种原因不允许您使用协程。使用协程,更容易实现这样的结果。考虑使用它们,尤其是看看它们解决问题的方法。

在您的情况下,我会使用 - CountDownLatch

您的代码将与此类似:

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

MyTasklatch.countDown()当你的工作完成时,引擎盖下应该调用。

latch.await()抛出InterruptedException,所以它应该被处理。

注意:无论如何,它会阻塞您当前所在的线程。最简单的方法是将此逻辑迁移到 Runnable 并提供回调:

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();
            }
        }

之后,您可以将任务提交到您的service. 注意:您的回调将从执行线程调用,因此您不能从它访问 UI。

这是一个不错的简单教程,希望对您有所帮助。

更新:

需要明确Callback的是 - 您的自定义界面会在工作完成时通知您。继续使用 SAM,例如:

interface WorkDoneCallback{
    void workWasDone();
}

PS要重定向主线程上的调用,只需在后台使用HandlerwithmainLooperrunOnUiThread().


推荐阅读