如何在Executor/FutureTask流程中用Lambda实现Android异步任务回调?
问题描述
现有如下异步任务相关代码:
public interface TaskCallback { void onTaskCompleted(Boolean result); void onTaskFailed(Exception e); } public class AsyncTaskExample { private final Executor executor = Executors.newSingleThreadExecutor(); public void executeAsyncTask(TaskCallback callback) { FutureTask<Boolean> taskSyncFiles = new FutureTask<>(() -> { // 具体任务逻辑 return true; }); executor.execute(taskSyncFiles); executor.execute(() -> { try { Boolean result = taskSyncFiles.get(); callback.onTaskCompleted(result); } catch (InterruptedException | ExecutionException e) { callback.onTaskFailed(e); } }); } }
希望在Android Activity中通过Lambda表达式分别传入完成和失败回调,调用方式如下,但无法正常运行:
myTask.executeAsyncTask(result -> { System.out.println("Task completed with result: " + result); }, e -> { e.printStackTrace(); });
请问该如何正确实现?
解决方案
问题核心是你定义的executeAsyncTask方法仅接收一个TaskCallback接口参数,但调用时传入了两个Lambda表达式。以下是两种可行的实现方案:
方案一:新增重载方法,拆分回调参数
- 先定义两个独立的函数式接口,分别对应成功和失败回调:
@FunctionalInterface public interface OnSuccessCallback { void onSuccess(Boolean result); } @FunctionalInterface public interface OnFailureCallback { void onFailure(Exception e); }
- 在
AsyncTaskExample中新增重载的executeAsyncTask方法,接收上述两个回调参数:
public class AsyncTaskExample { private final Executor executor = Executors.newSingleThreadExecutor(); // 保留原有方法,兼容旧调用逻辑 public void executeAsyncTask(TaskCallback callback) { FutureTask<Boolean> taskSyncFiles = new FutureTask<>(() -> { // 具体任务逻辑 return true; }); executor.execute(taskSyncFiles); executor.execute(() -> { try { Boolean result = taskSyncFiles.get(); callback.onTaskCompleted(result); } catch (InterruptedException | ExecutionException e) { callback.onTaskFailed(e); } }); } // 新增重载方法,支持拆分回调传入 public void executeAsyncTask(OnSuccessCallback successCallback, OnFailureCallback failureCallback) { FutureTask<Boolean> taskSyncFiles = new FutureTask<>(() -> { // 具体任务逻辑 return true; }); executor.execute(taskSyncFiles); executor.execute(() -> { try { Boolean result = taskSyncFiles.get(); successCallback.onSuccess(result); } catch (InterruptedException | ExecutionException e) { failureCallback.onFailure(e); } }); } }
- 现在即可在Activity中按预期方式调用:
AsyncTaskExample myTask = new AsyncTaskExample(); myTask.executeAsyncTask(result -> { // Android中子线程不能更新UI,需切换到主线程操作 runOnUiThread(() -> { Log.d("TaskLog", "Task completed with result: " + result); }); }, e -> { e.printStackTrace(); });
方案二:给TaskCallback添加静态构造方法
如果不想新增接口,可以通过给TaskCallback添加静态方法,快速构建实例,适配Lambda写法:
public interface TaskCallback { void onTaskCompleted(Boolean result); void onTaskFailed(Exception e); // 静态方法:快速创建包含双回调的实例 static TaskCallback of(OnSuccessCallback success, OnFailureCallback failure) { return new TaskCallback() { @Override public void onTaskCompleted(Boolean result) { success.onSuccess(result); } @Override public void onTaskFailed(Exception e) { failure.onFailure(e); } }; } } // 仍需定义两个基础函数式接口 @FunctionalInterface public interface OnSuccessCallback { void onSuccess(Boolean result); } @FunctionalInterface public interface OnFailureCallback { void onFailure(Exception e); }
调用方式如下:
myTask.executeAsyncTask(TaskCallback.of( result -> { runOnUiThread(() -> { Log.d("TaskLog", "Task completed: " + result); }); }, e -> { e.printStackTrace(); } ));
关键注意事项
- UI线程切换:Android中子线程无法更新UI,回调内如果需要操作UI,必须通过
runOnUiThread、Handler或LiveData切换到主线程。 - 资源释放:使用
Executors.newSingleThreadExecutor()创建的线程池,需在Activity销毁时关闭,避免内存泄漏:
@Override protected void onDestroy() { super.onDestroy(); // 需将executor改为可访问,比如设为public或提供shutdown方法 myTask.executor.shutdown(); }
内容的提问来源于stack exchange,提问作者markzzz
相关产品推荐
相关产品推荐

