You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中如何并行调用loadItems()并在全部完成后发送成功事件?

并行执行多个loadItems()并等待全部成功后触发事件的解决方案

嘿,我明白你的困扰——想要让多个继承自Item的类的loadItems()并行执行,还得等所有都成功完成后再发送事件对吧?这里给你几个实用的Android环境下的解决方案:

方案一:用CountDownLatch配合异步任务(适合Java旧代码)

CountDownLatch是Java并发包里的工具,能帮你精准等待指定数量的任务全部完成,步骤如下:

  1. 先修改loadItems(),把原来的同步逻辑放到AsyncTask里,任务成功完成后调用latch.countDown():
// 定义计数器,数量等于你要执行的任务总数
int totalTasks = 4;
CountDownLatch completionLatch = new CountDownLatch(totalTasks);

// 以CarMan为例,其他类同理修改
class CarMan extends Item {
    @Override
    public void loadItems() {
        new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected Boolean doInBackground(Void... voids) {
                // 把原来loadItems()里的同步创建对象逻辑写在这里
                return true; // 返回任务是否成功完成
            }

            @Override
            protected void onPostExecute(Boolean isSuccess) {
                if (isSuccess) {
                    completionLatch.countDown(); // 成功完成,计数器减1
                } else {
                    // 这里可根据需求处理失败:比如直接计数减1,或者抛出异常中断等待
                    completionLatch.countDown();
                }
            }
        }.execute();
    }
}
  1. 启动所有任务后,用一个异步任务等待计数器归零,然后发送成功事件:
// 启动所有任务
CarMan carMan = new CarMan(); carMan.loadItems();
TruckMan truckMan = new TruckMan(); truckMan.loadItems();
BikeMan bikeMan = new BikeMan(); bikeMan.loadItems();
CycleMan cycleMan = new CycleMan(); cycleMan.loadItems();

// 等待所有任务完成后触发事件
new AsyncTask<Void, Void, Void>() {
    @Override
    protected Void doInBackground(Void... voids) {
        try {
            completionLatch.await(); // 阻塞直到所有任务完成
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void unused) {
        // 所有任务都成功完成啦,这里发送你的成功事件
        sendSuccessEvent();
    }
}.execute();

方案二:用任务集合跟踪完成状态(更灵活)

如果不想用CountDownLatch,也可以维护一个线程安全的集合来记录每个任务的结果,每次任务完成后检查是否全部完成:

// 线程安全的集合,用来保存每个任务的成功状态
List<Boolean> taskResults = Collections.synchronizedList(new ArrayList<>());
int totalTasks = 4;

// 修改loadItems()逻辑
class CarMan extends Item {
    @Override
    public void loadItems() {
        new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected Boolean doInBackground(Void... voids) {
                // 原同步逻辑
                return true;
            }

            @Override
            protected void onPostExecute(Boolean isSuccess) {
                taskResults.add(isSuccess);
                checkIfAllDone(); // 每次完成都检查是否全部任务结束
            }
        }.execute();
    }
}

// 检查所有任务是否完成并全部成功的方法
private void checkIfAllDone() {
    if (taskResults.size() == totalTasks) {
        // 验证所有任务都成功
        boolean allSuccess = taskResults.stream().allMatch(result -> result);
        if (allSuccess) {
            sendSuccessEvent();
        } else {
            // 处理有任务失败的情况,比如发送失败事件
        }
    }
}

// 启动任务和之前一样
CarMan carMan = new CarMan(); carMan.loadItems();
TruckMan truckMan = new TruckMan(); truckMan.loadItems();
BikeMan bikeMan = new BikeMan(); bikeMan.loadItems();
CycleMan cycleMan = new CycleMan(); cycleMan.loadItems();

方案三:用ExecutorService替代AsyncTask(推荐,AsyncTask已废弃)

Android 11开始AsyncTask已经被废弃,官方推荐用ExecutorService处理异步任务,示例如下:

// 创建线程池,大小根据任务数量调整
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
List<Callable<Boolean>> taskList = new ArrayList<>();

// 把每个类的loadItems()改成同步方法(比如叫loadItemsSync),包装成Callable
taskList.add(() -> {
    CarMan carMan = new CarMan();
    return carMan.loadItemsSync();
});
taskList.add(() -> {
    TruckMan truckMan = new TruckMan();
    return truckMan.loadItemsSync();
});
taskList.add(() -> {
    BikeMan bikeMan = new BikeMan();
    return bikeMan.loadItemsSync();
});
taskList.add(() -> {
    CycleMan cycleMan = new CycleMan();
    return cycleMan.loadItemsSync();
});

// 执行所有任务并等待完成
try {
    // invokeAll会等待所有任务完成才返回
    List<Future<Boolean>> taskFutures = taskExecutor.invokeAll(taskList);
    boolean allTasksSuccess = true;
    for (Future<Boolean> future : taskFutures) {
        if (!future.get()) {
            allTasksSuccess = false;
            break;
        }
    }
    if (allTasksSuccess) {
        sendSuccessEvent();
    }
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
} finally {
    taskExecutor.shutdown(); // 一定要关闭线程池
}

小提醒

  • 如果你的项目是Kotlin,可以用协程的async和awaitAll来实现,代码会更简洁。
  • 不管用哪种方案,都要处理任务失败的情况——比如某个loadItems()执行失败时,你需要决定是继续等待其他任务,还是直接终止并发送失败事件。

内容的提问来源于stack exchange,提问作者Happy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:13:38