Android @带ViewModel的RawQuery
我遵循本教程,一切正常。现在,我正在尝试实现@RawQuery并使用ViewModel显示LiveData。我想显示具有特定列值(在本例中为字符串)的项目列表。在这段代码中,似乎是我所需应用程序功能的解决方案:Android @带ViewModel的RawQuery,android,android-room,android-viewmodel,Android,Android Room,Android Viewmodel,我遵循本教程,一切正常。现在,我正在尝试实现@RawQuery并使用ViewModel显示LiveData。我想显示具有特定列值(在本例中为字符串)的项目列表。在这段代码中,似乎是我所需应用程序功能的解决方案: @Dao interface RawDao { @RawQuery(observedEntities = User.class) LiveData<List<User>> getUsers(SupportSQLiteQuery query);
@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"));
存储库
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;
}
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);
}
});
创建活动时,我的应用程序崩溃,并出现错误:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.arch.persistence.db.SupportSQLiteQuery.getSql()' on a null object reference
我不明白为什么我的对象没有被创建,什么时候应该被创建。Logcat还指出ShotDao_Impl.java生成的源文件中的A行和B行
@Override
public LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery) {
final SupportSQLiteQuery _internalQuery = supportSQLiteQuery;
return new ComputableLiveData<List<Shot>>() { // row A
private Observer _observer;
@Override
protected List<Shot> compute() {
if (_observer == null) {
_observer = new Observer("shots") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_internalQuery); // row B
try {
final List<Shot> _result = new ArrayList<Shot>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Shot _item;
_item = __entityCursorConverter_comExampleAndroidWrappDatabaseShot(_cursor);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
}.getLiveData();
}
@覆盖
公共LiveData getNameColumn(SupportSQLiteQuery SupportSQLiteQuery){
最终支持SQLiteQuery _internalQuery=SupportSQLiteQuery;
返回新的ComputeableLiveData(){//行A
私人观察员;
@凌驾
受保护列表计算(){
如果(_observer==null){
_观察者=新观察者(“快照”){
@凌驾
public void onInvalidated(@NonNull Set tables){
使无效();
}
};
__db.getInvalizationTracker().addWeakObserver(_observer);
}
最终游标_Cursor=u db.query(_internalQuery);//行B
试一试{
最终列表_result=newarraylist(_cursor.getCount());
while(_cursor.moveToNext()){
最后一杆项目;
_item=\u entityCursorConverter\u ComExample和IDWrappDatabaseShot(\u光标);
_结果.添加(_项);
}
返回结果;
}最后{
_cursor.close();
}
}
}.getLiveData();
}
viewmodel中的这一行给出了错误信息。您正在为房间数据库设置mSimpleSQLiteQuery
,该数据库为空
mNameColumn=mRepository.getNameColumn(mSimpleSQLiteQuery)代码>
您应该从viewmodel中删除上面的行,并修改getNameColumn()
函数,如下所示:
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
公共LiveData getNameColumn(SimpleSQLiteQuery SimpleSQLiteQuery){
返回mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
编辑:
您可以通过修改DAO来简化代码。您可以直接将参数传递到DAO中
例如
@Query(“从快照中选择*,其中nameColumn=:columnName”)
LiveData getNameColumn(字符串columnName);
使用此功能,您可以根据列名检索
快照
,viewmodel中的这一行显示错误。您正在为房间数据库设置mSimpleSQLiteQuery
,该数据库为空
mNameColumn=mRepository.getNameColumn(mSimpleSQLiteQuery)代码>
您应该从viewmodel中删除上面的行,并修改getNameColumn()
函数,如下所示:
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
公共LiveData getNameColumn(SimpleSQLiteQuery SimpleSQLiteQuery){
返回mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
编辑:
您可以通过修改DAO来简化代码。您可以直接将参数传递到DAO中
例如
@Query(“从快照中选择*,其中nameColumn=:columnName”)
LiveData getNameColumn(字符串columnName);
使用此功能,您可以根据列名检索
shots
在执行ViewModel构造函数时,使用null
mSimpleSQLiteQuery
在ViewModel中创建mNameColumn
活动数据。您正在getNameColumn
中设置此值,但请注意,您的livedata不知道此新值
因此,为
LiveData getNameColumn(SupportSQLiteQuery SupportSQLiteQuery)执行ShotDao
代码>接收导致崩溃的null
支持SQLiteQuery。在执行ViewModel构造函数时,使用null
mSimpleSQLiteQuery
创建ViewModel中的mNameColumn
活动数据。您正在getNameColumn
中设置此值,但请注意,您的livedata不知道此新值
因此,为LiveData getNameColumn(SupportSQLiteQuery SupportSQLiteQuery)执行ShotDao
代码>接收null
SupportSQLiteQuery,这将导致崩溃。感谢您提供的解决方案和简化示例!感谢您提供的解决方案和简化示例!谢谢你的意见!谢谢你的意见!
@Override
public LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery) {
final SupportSQLiteQuery _internalQuery = supportSQLiteQuery;
return new ComputableLiveData<List<Shot>>() { // row A
private Observer _observer;
@Override
protected List<Shot> compute() {
if (_observer == null) {
_observer = new Observer("shots") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_internalQuery); // row B
try {
final List<Shot> _result = new ArrayList<Shot>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Shot _item;
_item = __entityCursorConverter_comExampleAndroidWrappDatabaseShot(_cursor);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
}.getLiveData();
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
@Query("SELECT * FROM shots WHERE nameColumn = :columnName")
LiveData<List<Shot>> getNameColumn(String columnName);