简体   繁体   English

Room - LiveData 观察者不会在数据库更新时触发

[英]Room - LiveData observer does not trigger when database is updated

I am trying to find out in the code below, why is it that Room's LiveData observable does not give me new shifts once I populate the database with new data.我试图在下面的代码中找出为什么在我用新数据填充数据库后 Room 的 LiveData observable 没有给我新的班次。

This is put on my activity's onCreate method:这是放在我的活动的 onCreate 方法上:

shiftsViewModel = ViewModelProviders.of(this).get(ShiftsViewModel.class);
shiftsViewModel
            .getShifts()
            .observe(this, this::populateAdapter);

This is the populateAdapter method:这是 populateAdapter 方法:

private void populateAdapter(@NonNull final List<Shift> shifts){

    recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(shifts));
}

I also have the following code that populates the database (I use RxJava to do the work on an IO thread since Room needs its code to be called outside the main thread):我还有以下填充数据库的代码(我使用 RxJava 在 IO 线程上完成工作,因为 Room 需要在主线程之外调用其代码):

@Override
public Observable<List<Shift>> persistShifts(@NonNull final List<Shift> shifts){

    return Observable.fromCallable(() -> {

        appDatabase.getShiftDao().insertAll(shifts);
        return shifts;
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());
}

The problem I have occurs when I call persistShifts after I start observing my shiftsViewModel.当我开始观察我的 shiftsViewModel 后调用 persistShifts 时,我遇到的问题。 I would expect that my observer (LiveData) would be triggered with all the newly added shifts.我希望所有新添加的班次都会触发我的观察者 (LiveData)。 It turns out the observer is triggered, but an empty list of shifts is returned instead.结果发现观察者被触发了,但返回的是一个空的班次列表。 The only way to make it "work" is if I leave the activity (therefore destroying the current ViewModel) and enter again.让它“工作”的唯一方法是我离开活动(因此破坏当前的ViewModel)并再次进入。 This time the viewModel's LiveData gives me all the shifts previously persisted, as expected.这次 viewModel 的 LiveData 给了我之前坚持的所有转变,正如预期的那样。

Here is the rest of the code:下面是代码的其余部分:

@Entity
public class Shift{

   @PrimaryKey
   private long id;

   private String start;
   private String end;
   private String startLatitude;
   private String startLongitude;
   private String endLatitude;
   private String endLongitude;
   private String image;
   ...

DAO:道:

@Dao
public interface ShiftDAO {

   @Query("SELECT * FROM shift")
   LiveData<List<Shift>> getAll();

   @Query("SELECT * FROM shift WHERE id = :id")
   LiveData<Shift> getShiftById(long id);

   @Insert(onConflict = OnConflictStrategy.REPLACE)
   void insertAll(List<Shift> shifts);
}

ViewModel:视图模型:

public class ShiftsViewModel extends AndroidViewModel{

   private final ISQLDatabase sqlDatabase;

   private MutableLiveData<Shift> currentShift;
   private LiveData<List<Shift>> shifts;
   private boolean firstTimeCreated;


   public ShiftsViewModel(final Application application){

      super(application);

      this.sqlDatabase = ((ThisApplication) application).getSQLDatabase();
      this.firstTimeCreated = true;
   }

   public MutableLiveData<Shift> getCurrentlySelectedShift(){

      if(currentShift == null){
         currentShift = new MutableLiveData<>();
      }

      return currentShift;
   }

   public LiveData<List<Shift>> getShifts() {

      if(shifts == null){
         shifts = sqlDatabase.queryAllShifts();
      }

     return shifts;
   }

   public void setCurrentlySelectedShift(final Shift shift){

      currentShift = getCurrentlySelectedShift();

      currentShift.setValue(shift);
   }

   public boolean isFirstTimeCreated(){
      return firstTimeCreated;
   }

   public void alreadyUsed(){
      firstTimeCreated = false;
   }
}

Why am I not getting the list of shifts I persist in the observe() callback straightaway?为什么我没有立即获得我在 observe() 回调中坚持的班次列表?

I had a similar problem using Dagger 2 that was caused by having different instances of the Dao, one for updating/inserting data, and a different instance providing the LiveData for observing.我在使用 Dagger 2 时遇到了类似的问题,这是由 Dao 的不同实例引起的,一个用于更新/插入数据,另一个实例提供用于观察的 LiveData。 Once I configured Dagger to manage a singleton instance of the Dao, then I could insert data in the background (in my case in a Service) while observing LiveData in my Activity - and the onChange() callback would be called.一旦我将 Dagger 配置为管理 Dao 的单例实例,那么我就可以在后台插入数据(在我的情况下是在服务中),同时在我的 Activity 中观察 LiveData - 并且将调用 onChange() 回调。

It comes down to the instance of the Dao must be the same instance that is inserting/updating data and providing LiveData for observation.归结为 Dao 的实例必须是插入/更新数据并提供 LiveData 以供观察的同一个实例。

In my case, it was because I was using a MediatorLiveData to convert the entities returned from the database and forgot to call setValue() with the converted result, so the mediator was only relying requests to the database but never notifying results.就我而言,这是因为我使用 MediatorLiveData 来转换从数据库返回的实体,而忘记使用转换后的结果调用setValue() ,因此中介器仅依赖于对数据库的请求,而从不通知结果。

override fun getItems() = MediatorLiveData<List<Item>>().apply {
    addSource(itemDao().getItems()) {
        // I was previously only converting the items, without calling 'value ='
        value = it.map(ItemWithTags::toDto)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 LiveData 观察者不会在回调时触发 - LiveData observer does not trigger on a callback 房间数据库查询后 LiveData 不更新观察者 - LiveData not updating observer after Room database query 在Room数据库中的runInTransaction()期间触发LiveData观察器 - LiveData observer is triggered during runInTransaction() in Room database LiveData如何知道房间数据库中何时更改数据? - How does LiveData know when data is changed in Room Database? SyncAdapter中的Singleton Room数据库用于触发LiveData - Singleton Room database in SyncAdapter to trigger LiveData Android Room Database-LiveData-更新/插入/删除,跳过观察者(回调) - Android Room Database - LiveData - Update/Insert/Delete, skip observer (callback) 房间数据库:Livedata 观察者大于实际行大小 - Room Database: Livedata observer more than actual row size Room :来自 Dao 的 LiveData 将在每次更新时触发 Observer.onChanged,即使 LiveData 值没有变化 - Room : LiveData from Dao will trigger Observer.onChanged on every Update, even if the LiveData value has no change 在 Room DB 上插入不会在 Activity 上触发观察者 - Insert on Room DB does not trigger Observer on Activity Android Room LiveData Observer 未更新 - Android Room LiveData Observer not updating
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM