Android使用Room从SQLite获取单个对象的repository层代码如何编写?
问题根因
Room 默认禁止在主线程执行数据库操作,你原有代码中直接调用同步方法 Lens getLensById(int lensId) 属于阻塞IO操作,在主线程执行会直接抛出异常,必须通过异步方式执行。
方案1:沿用现有 AsyncTask 实现(适配现有代码风格)
异步操作无法直接同步返回结果,需要通过回调接口传递查询结果:
1. Repository 层实现
public class LensRepository { private LensDao lensDao; // 定义查询结果回调接口 public interface GetLensCallback { void onLensLoaded(Lens lens); } // 异步查询任务 private static class GetLensByIdAsyncTask extends AsyncTask<Integer, Void, Lens> { private final LensDao lensDao; private final GetLensCallback callback; private GetLensByIdAsyncTask(LensDao lensDao, GetLensCallback callback) { this.lensDao = lensDao; this.callback = callback; } @Override protected Lens doInBackground(Integer... ids) { return lensDao.getLensById(ids[0]); } @Override protected void onPostExecute(Lens lens) { // 结果自动回调到主线程 callback.onLensLoaded(lens); } } // 对外暴露的查询方法 public void getLensById(int id, GetLensCallback callback) { new GetLensByIdAsyncTask(lensDao, callback).execute(id); } // 原有其他方法比如delete保留即可 }
2. 调用层(Activity/ViewHolder)修改
原有直接返回对象的写法无法适配异步逻辑,需要改为传入回调处理结果:
// Activity 中调用示例 repository.getLensById(targetLensId, new LensRepository.GetLensCallback() { @Override public void onLensLoaded(Lens lens) { // 此处拿到查询到的Lens对象,执行UI更新等后续操作 } });
方案2:更推荐的 LiveData 实现(适配你已有的LiveData使用习惯)
你已经在使用LiveData加载全量数据,Room原生支持返回LiveData类型的查询结果,会自动在后台线程执行查询,无需手动编写异步任务,还能自动监听数据库变化:
1. 修改Dao层方法签名
@Query("SELECT * FROM lens_table WHERE id = :lensId LIMIT 1") LiveData<Lens> getLensById(int lensId);
2. Repository层实现
public LiveData<Lens> getLensById(int id) { return lensDao.getLensById(id); }
3. 调用层使用
// Activity中调用示例 repository.getLensById(targetLensId).observe(this, lens -> { // 拿到Lens对象,执行后续操作 });
注意:AsyncTask 已在Android 11中被官方废弃,方案2实现更简洁,还支持数据变化自动通知,更符合Android开发最佳实践。
内容的提问来源于stack exchange,提问作者Zudy
相关产品推荐
相关产品推荐

