在ROOM中复用Callable代码:MVVM架构TODO应用代码优化问询
优化方案
1. 核心复用:提取通用数据库执行方法
你的代码重复了线程池创建、Callable封装、异常处理逻辑,首先抽取出通用方法,将具体的DAO操作作为参数传入:
首先在你的Repository类中定义全局复用的线程池(避免每次创建新线程池带来的开销):
private final ExecutorService dbExecutor = Executors.newSingleThreadExecutor();
然后编写通用执行方法,统一处理线程提交、异常捕获:
/** * 通用数据库操作执行方法 * @param operation 具体的DAO操作逻辑 * @return 操作结果,异常时返回空集合(针对列表类型)或null */ private <T> T executeDbOperation(Callable<T> operation) { try { return dbExecutor.submit(operation).get(); } catch (ExecutionException e) { // 可根据需求添加自定义异常处理,比如日志上报 Throwable rootCause = e.getCause(); Log.e("DB_OP", "数据库操作失败", rootCause); } catch (InterruptedException e) { e.printStackTrace(); // 恢复线程中断状态,避免影响后续逻辑 Thread.currentThread().interrupt(); } // 针对集合类型返回空集合,避免上层空指针 if (operation instanceof Callable<? extends Collection>) { return (T) Collections.emptyList(); } return null; }
2. 简化原有业务方法
利用Java 8+的Lambda表达式替代匿名Callable,原有方法可以简化为一行代码:
public List<Task> getAllUnCompletedTasksAsList() { return executeDbOperation(() -> appDataBase.taskDao().getAllUnCompletedTasksAsList()); } public List<Task> getCompletedTasksAsList() { return executeDbOperation(() -> appDataBase.taskDao().getCompletedTasksAsList()); } public List<Task> getWeeklyTasksAsList() { return executeDbOperation(() -> appDataBase.taskDao().getWeeklyTasksAsList()); }
3. 线程池生命周期管理
为避免内存泄漏,在Repository销毁时关闭线程池(比如在ViewModel的onCleared()方法中调用):
public void cleanup() { dbExecutor.shutdown(); }
4. 更贴合MVVM的进阶优化
当前使用future.get()是阻塞式调用,如果在主线程调用会导致UI卡顿。ROOM本身支持LiveData自动处理线程切换,更符合MVVM的响应式设计:
用LiveData实现异步非阻塞
- 在DAO层定义返回LiveData的方法:
@Query("SELECT * FROM tasks WHERE completed = 0") LiveData<List<Task>> getAllUnCompletedTasks(); @Query("SELECT * FROM tasks WHERE completed = 1") LiveData<List<Task>> getCompletedTasks(); @Query("SELECT * FROM tasks WHERE due_date >= :startOfWeek AND due_date <= :endOfWeek") LiveData<List<Task>> getWeeklyTasks(long startOfWeek, long endOfWeek);
- 在Repository直接返回LiveData,ROOM会自动在后台线程执行查询,主线程观察:
public LiveData<List<Task>> getAllUnCompletedTasks() { return appDataBase.taskDao().getAllUnCompletedTasks(); } public LiveData<List<Task>> getCompletedTasks() { return appDataBase.taskDao().getCompletedTasks(); } public LiveData<List<Task>> getWeeklyTasks(long startOfWeek, long endOfWeek) { return appDataBase.taskDao().getWeeklyTasks(startOfWeek, endOfWeek); }
- 在ViewModel中观察LiveData,自动更新UI:
public class TaskViewModel extends ViewModel { private final TaskRepository repository; public final LiveData<List<Task>> unCompletedTasks; public TaskViewModel(TaskRepository repository) { this.repository = repository; unCompletedTasks = repository.getAllUnCompletedTasks(); } }
这种方式完全不需要手动处理线程,代码更简洁且符合MVVM架构的响应式理念。
内容的提问来源于stack exchange,提问作者HoLoGram
相关产品推荐
相关产品推荐

