Dao Room数据库如何对amount列求和并展示到TextView中
问题分析
初始版本求和始终返回0的原因
AsyncTask为异步执行组件,调用execute()方法后主线程不会阻塞等待异步任务执行完成,会立刻读取sumValue返回。此时doInBackground中的数据库查询逻辑还未执行,sumValue仍为int类型的默认初始值0,因此返回结果始终为0,该问题与DAO查询语句无关。
改用观察者后出现空指针的原因
触发空指针有两个常见原因:
- 当Item表无数据时,SQLite的
SUM()函数会返回NULL,如果DAO层方法返回值声明为基本类型int,Room会尝试将null自动拆箱为int,直接触发空指针异常 - 调整为LiveData观察实现时,未同步修改DAO层方法的返回值为
LiveData<Integer>,ViewModel/Repository层没有正确传递可观察数据,导致Observer接收到null值
标准实现方案
- 修改DAO层方法定义,返回LiveData类型的结果,使用包装类型Integer避免空值拆箱错误:
@Query("SELECT SUM(amount) as total FROM Item") public LiveData<Integer> getTotalSum();
- Repository层直接返回DAO层的LiveData对象:
public LiveData<Integer> sumAllItems(){ return dao.getTotalSum(); }
- ViewModel层直接返回Repository层的LiveData对象:
public LiveData<Integer> sumAllItems() { return repository.sumAllItems(); }
- Activity层观察数据时增加空值判断,兼容空表场景:
mainViewModel.sumAllItems().observe(this, new Observer<Integer>() { @Override public void onChanged(Integer integer) { int total = integer != null ? integer : 0; totalAmount.setText(total + " kr"); } });
内容的提问来源于stack exchange,提问作者Emsko
相关产品推荐
相关产品推荐

