Android Room单列更新自定义查询MVVM架构下AsyncTask传参问题
解决AsyncTask参数限制适配多参数DAO更新的问题
嘿,我完全懂你遇到的困扰——AsyncTask只能传递单一类型的参数,可你的DAO方法偏偏需要两个参数来定位行并更新列,确实有点卡壳。不过别慌,这里有几个适配你现有MVVM架构的简单解决方案,挑一个适合你的就行:
方案一:用Pair或自定义包装类传递多参数
既然AsyncTask只能传一个对象,那我们就把两个参数打包成一个对象。Android自带的Pair类就很适合干这个事,当然你也可以自己写个简单的POJO类。
步骤调整:
- DAO保持不变:你的原DAO方法没问题,继续用:
@Query("UPDATE CbtTable SET twistedThinkingPK = :twistedThinkingPK WHERE cbtId = :cbtId") void updateTwistedThinking(long cbtId, long twistedThinkingPK);
- 修改AsyncTask的参数类型:把泛型改成
Pair<Long, Long>,在后台任务里拆分参数:
private static class UpdateTwistedThinkingAsyncTask extends AsyncTask<Pair<Long, Long>, Void, Void> { private CbtDao mCbtDao; UpdateTwistedThinkingAsyncTask(CbtDao cbtDao) { mCbtDao = cbtDao; } @Override protected Void doInBackground(Pair<Long, Long>... params) { long targetCbtId = params[0].first; long newTwistedPK = params[0].second; mCbtDao.updateTwistedThinking(targetCbtId, newTwistedPK); return null; } }
- 上层Repository/ViewModel/Activity同步调整:
- Repository:
public void updateTwistedThinking(long cbtId, long twistedThinkingPK) { new UpdateTwistedThinkingAsyncTask(cbtDao).execute(new Pair<>(cbtId, twistedThinkingPK)); }
- ViewModel:
public void updateTwistedThinking(long cbtId, long twistedThinkingPK) { cbtRepository.updateTwistedThinking(cbtId, twistedThinkingPK); }
- Activity:
// 注意这里需要传入要更新的行的cbtId(比如从选中的条目获取) public void updateTwistedThinkingCbtTable(long targetCbtId, long twistedThinkingPK) { cbtViewModel.updateTwistedThinking(targetCbtId, twistedThinkingPK); }
方案二:让CbtTable携带主键信息(更贴合现有代码)
其实你的CbtTable作为数据库实体,肯定包含主键cbtId对吧?那我们只需要在Activity创建对象时把主键也设置进去,就能从对象里直接拿到两个参数了,改动最小:
步骤调整:
- Activity补充主键设置:
// 确保你已经获取到要更新的行的cbtId public void updateTwistedThinkingCbtTable(long targetCbtId, long twistedThinkingPK) { CbtTable cbtTable = new CbtTable(); cbtTable.setCbtId(targetCbtId); // 添加上主键 cbtTable.setTwistedThinkingPK(twistedThinkingPK); cbtViewModel.updateTwistedThinking(cbtTable); }
- 修改AsyncTask的调用逻辑:从传入的
CbtTable对象里提取两个参数:
@Override protected Void doInBackground(CbtTable... cbtTables) { CbtTable targetTable = cbtTables[0]; mCbtDao.updateTwistedThinking(targetTable.getCbtId(), targetTable.getTwistedThinkingPK()); return null; }
- DAO/Repository/ViewModel完全不用改:保持你原来的代码就行,这个方案的改动成本最低。
额外建议:考虑替换AsyncTask(进阶优化)
顺便提一句,AsyncTask已经被官方废弃了,如果你以后想优化代码结构,推荐用Kotlin协程或者RxJava来做异步操作,它们不仅没有参数限制,代码也更简洁。比如用协程的话,Repository可以改成这样:
// 需要先引入Coroutines依赖 public void updateTwistedThinking(long cbtId, long twistedThinkingPK) { CoroutineScope(Dispatchers.IO).launch { cbtDao.updateTwistedThinking(cbtId, twistedThinkingPK); } }
这样连AsyncTask的类都不用写了,是不是清爽很多?不过这个属于优化项,先解决当前问题的话,前两个方案足够用了。
内容的提问来源于stack exchange,提问作者AndroidDev123
相关产品推荐
相关产品推荐

