Android中如何并行调用loadItems()并在全部完成后发送成功事件?
并行执行多个
loadItems()并等待全部成功后触发事件的解决方案 嘿,我明白你的困扰——想要让多个继承自Item的类的loadItems()并行执行,还得等所有都成功完成后再发送事件对吧?这里给你几个实用的Android环境下的解决方案:
方案一:用CountDownLatch配合异步任务(适合Java旧代码)
CountDownLatch是Java并发包里的工具,能帮你精准等待指定数量的任务全部完成,步骤如下:
- 先修改
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(); } }
- 启动所有任务后,用一个异步任务等待计数器归零,然后发送成功事件:
// 启动所有任务 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
相关产品推荐
相关产品推荐

