Room框架下@RawQuery结合ViewModel展示LiveData遇空指针异常求助
解决@RawQuery的NullPointerException问题
让我们一步步拆解你遇到的空指针问题:
问题根源
你的崩溃核心原因是传给Dao的SupportSQLiteQuery为null,这个null值是从Repository和ViewModel的初始化逻辑里连锁产生的:
- 在
ShotRepository构造函数中,你初始化mSimpleSQLiteQuery为null,直接调用mShotDao.getNameColumn(mSimpleSQLiteQuery)生成了一个基于无效查询的LiveData。后续的getNameColumn方法只是更新了成员变量mSimpleSQLiteQuery,但mNameColumn始终是最初那个用null生成的实例——当这个LiveData开始计算数据时,__db.query(_internalQuery)里的_internalQuery是null,自然触发空指针。 ShotViewModel重复了同样的错误:构造时传null给Repository拿到了有问题的LiveData,后续调用getNameColumn只是更新自己的mSimpleSQLiteQuery,并没有重新获取基于有效查询的LiveData,导致Activity监听的还是那个失效的实例。
修复方案
我们需要调整Repository和ViewModel的逻辑,让每次调用getNameColumn时,都基于传入的有效查询返回新的LiveData:
1. 修改ShotRepository
移除冗余的成员变量,每次调用方法时直接传入查询并返回Dao的结果:
public class ShotRepository { private ShotDao mShotDao; public ShotRepository(Application application) { WrappShotDatabase database = WrappShotDatabase.getDatabase(application); mShotDao = database.shotDao(); } // 直接返回基于传入查询的LiveData public LiveData<List<Shot>> getNameColumn(SimpleSQLiteQuery simpleSQLiteQuery) { return mShotDao.getNameColumn(simpleSQLiteQuery); } }
2. 修改ShotViewModel
同样移除冗余成员变量,直接转发Repository的调用:
public class ShotViewModel extends AndroidViewModel { private ShotRepository mRepository; public ShotViewModel(Application application) { super(application); mRepository = new ShotRepository(application); } public LiveData<List<Shot>> getNameColumn(SimpleSQLiteQuery simpleSQLiteQuery) { return mRepository.getNameColumn(simpleSQLiteQuery); } }
3. 优化SQL查询(避免SQL注入风险)
你当前直接拼接字符串生成SQL存在安全隐患,建议改用参数化查询:
private SimpleSQLiteQuery simpleSQLiteQuery(String nameColumn) { String sql = "SELECT * FROM shots WHERE nameColumn = ?"; return new SimpleSQLiteQuery(sql, new Object[]{nameColumn}); }
验证修复
现在Activity的调用逻辑会正常工作:当你调用shotViewModel.getNameColumn(simpleSQLiteQuery(columnName))时,会生成一个基于有效查询的LiveData,Dao执行时不会再遇到null的SupportSQLiteQuery,空指针问题也就解决了。
内容的提问来源于stack exchange,提问作者gogi
相关产品推荐
相关产品推荐

