首页 > 解决方案 > @RawQuery 与 ViewModel

问题描述

我遵循了这个带视图的房间教程,一切都按预期工作。现在我正在尝试实现@RawQuery 并使用 ViewModel 显示 LiveData。我想显示具有特定列值的项目列表(在本例中为字符串)。在本文档中,此代码似乎是我想要的应用程序功能的解决方案:

@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"));

simpleSQLiteQuery(String nameColumn)我希望在将 nameColumn 值传递给返回的函数时在运行时构造我的读取查询new SimpleSQLiteQuery

这是我的代码:

@Dao
public interface ShotDao {

@RawQuery(observedEntities = Shot.class)
LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);

}

存储库

    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;
    }

活动

        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);
            }
        });

SimpleSQLiteQuery 方法

 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);
    }

创建 Activity 时,我的应用程序崩溃并出现错误:

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();
  }

标签: androidandroid-roomandroid-viewmodel

解决方案


ViewModel 中的mNameColumnLiveData 是在null mSimpleSQLiteQueryViewModel 构造函数执行时创建的。您正在设置它,getNameColumn但请注意您的 livedata 不知道这个新值。

ShotDao因此for的 implLiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);接收nullSupportSQLiteQuery 导致崩溃。


推荐阅读