@RawQuery与ViewModel

时间:2019-03-19 13:12:01

标签: android android-room android-viewmodel

我遵循了此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

2 个答案:

答案 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导致崩溃。