LiveData.getValue()在Room中返回null

Cod*_*meo 23 android android-room android-livedata android-architecture-components

Java POJO对象

public class Section {

    @ColumnInfo(name="section_id")
    public int mSectionId;

    @ColumnInfo(name="section_name")
    public String mSectionName;

    public int getSectionId() {
        return mSectionId;
    }

    public void setSectionId(int mSectionId) {
        this.mSectionId = mSectionId;
    }

    public String getSectionName() {
        return mSectionName;
    }

    public void setSectionName(String mSectionName) {
        this.mSectionName = mSectionName;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的查询方法

@Query("SELECT * FROM section")
LiveData<List<Section>> getAllSections();
Run Code Online (Sandbox Code Playgroud)

访问数据库

final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();
Run Code Online (Sandbox Code Playgroud)

在下一行,我正在检查sections.getValue()哪个总是给我null,虽然我在DataBase中有数据,后来我得到了onChanged()方法中的值.

sections.observe(this, new Observer<List<Section>>() {
    @Override
    public void onChanged(@Nullable List<Section> sections){

    }
});
Run Code Online (Sandbox Code Playgroud)

但是当我从查询中省略LiveData时,我正在按预期获取数据.查询方法:

@Query("SELECT * FROM section")
List<Section> getAllSections();
Run Code Online (Sandbox Code Playgroud)

访问数据库:

final List<Section> sections = mDb.sectionDAO().getAllSections();
Run Code Online (Sandbox Code Playgroud)

Cod*_*meo 16

我通过这种方法解决了这个问题

    private MediatorLiveData<List<Section>> mSectionLive = new MediatorLiveData<>();
    .
    .
    .

    @Override
    public LiveData<List<Section>> getAllSections() {
        final LiveData<List<Section>> sections = mDb.sectionDAO().getAllSections();

        mSectionLive.addSource(sections, new Observer<List<Section>>() {
            @Override
            public void onChanged(@Nullable List<Section> sectionList) {
               if(sectionList == null || sectionList.isEmpty()) {
                  // Fetch data from API
               }else{
                  mSectionLive.removeSource(sections);
                  mSectionLive.setValue(sectionList);
               }
            }
        });
        return mSectionLive;
    }
Run Code Online (Sandbox Code Playgroud)

  • 据我所知,`MediatorData`是完全没必要的.你可以使用`sections.observer()`将`Observer`直接添加到原始`LiveData`. (5认同)

sne*_*yan 14

在下一行,我正在检查sections.getValue(),它总是给我null,虽然我在DataBase中有数据,后来我在onChanged()方法中得到了值.

这是一种正常行为,因为返回LiveData的查询正在异步工作.那一刻的值为null.

所以调用这个方法

LiveData<List<Section>> getAllSections();
Run Code Online (Sandbox Code Playgroud)

你会在这里得到结果

sections.observe(this, new Observer<List<Section>>() {
@Override
public void onChanged(@Nullable List<Section> sections){

}
});
Run Code Online (Sandbox Code Playgroud)

来自文件:

除非您在构建器上调用allowMainThreadQueries(),否则Room不允许访问主线程上的数据库,因为它可能会长时间锁定UI.异步查询(返回LiveData或RxJava Flowable的查询)不受此规则的约束,因为它们在需要时在后台线程上异步运行查询.