我遵循了此Room With a View教程,一切正常。现在,我正在尝试实现@RawQuery并使用ViewModel显示LiveData。我想显示具有特定列值(在这种情况下为String)的项目列表。在this documentation中,此代码似乎是我所需的应用程序功能的解决方案:
@Dao
interface RawDao {
@RawQuery(observedEntities = User.class)
LiveData<List<User>> getUsers(SupportSQLiteQuery query);
}
LiveData<List<User>> liveUsers = rawDao.getUsers(
new SimpleSQLiteQuery("SELECT * FROM User ORDER BY name DESC"));
我希望将nameColumn值传递到返回simpleSQLiteQuery(String nameColumn)
的{{1}}函数中,以便在运行时构造读取查询。
这是我的代码:
Dao
new SimpleSQLiteQuery
存储库
@Dao
public interface ShotDao {
@RawQuery(observedEntities = Shot.class)
LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
}
ViewModel
private ShotDao mShotDao;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotRepository(Application application) {
WrappShotDatabase database = WrappShotDatabase.getDatabase(application);
mShotDao = database.shotDao();
mNameColumn = mShotDao.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
活动
private ShotRepository mRepository;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotViewModel(Application application) {
super(application);
mRepository = new ShotRepository(application);
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
SimpleSQLiteQuery方法
String columnName = mColumnName;
shotViewModel = ViewModelProviders.of(this).get(ShotViewModel.class);
shotViewModel.getNameColumn(simpleSQLiteQuery(columnName)).observe(this, new Observer<List<Shot>>() {
@Override
public void onChanged(@Nullable List<Shot> shots) {
mShotAdapter.submitList(shots);
}
});
创建活动后,我的应用程序崩溃了,并显示错误消息:
private SimpleSQLiteQuery simpleSQLiteQuery(String nameColumn) {
String select = "SELECT * FROM ";
String tableName = "shots";
String where = " WHERE nameColumn=\"";
String close = "\"";
return new SimpleSQLiteQuery(select + tableName + where + nameColumn + close);
}
我不安静地理解为什么不创建对象以及何时不创建对象。 Logcat还会指出ShotDao_Impl.java生成的源文件中的A行和B行。
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.arch.persistence.db.SupportSQLiteQuery.getSql()' on a null object reference
答案 0 :(得分:0)
viewmodel中的这一行会给您错误。您正在为房间db设置mSimpleSQLiteQuery
,该数据库为空。
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
您应该从viewmodel中删除上面的行,并像这样修改getNameColumn()
函数:
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
编辑:
您可以通过修改DAO来简化代码。您可以直接将参数传递到DAO中。
例如
@Query("SELECT * FROM shots WHERE nameColumn = :columnName")
LiveData<List<Shot>> getNameColumn(String columnName);
使用此功能,您可以根据列名检索shots
答案 1 :(得分:0)
在执行ViewModel构造函数时,使用mNameColumn
null
在ViewModel中创建mSimpleSQLiteQuery
LiveData。您已在getNameColumn
中进行了设置,但请注意,您的livedata不了解此新值。
因此ShotDao
的{{1}}的隐含接收LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
SupportSQLiteQuery导致崩溃。