Room - LiveData observer не запускается при обновлении базы данных

Я пытаюсь выяснить в коде ниже, почему это LiveData наблюдаемой комнаты не дает мне новые сдвиги, как только я заполняю базу данных новыми данными.

это ставится на метод onCreate моей деятельности:

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

это метод populateAdapter:

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

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

у меня также есть следующий код, который заполняет базу данных (я использую RxJava для выполнения работы над потоком ввода-вывода, так как номер должен быть вызван за пределами основного thread):

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

проблема у меня возникает, когда я вызываю persistShifts после того, как я начинаю наблюдать за своим shiftsViewModel. Я ожидал бы, что мой наблюдатель (LiveData) будет запущен со всеми новыми добавленными сдвигами. Оказывается, наблюдатель запускается, но вместо этого возвращается пустой список сдвигов. Единственный способ заставить его "работать" - это оставить действие (следовательно, уничтожить текущую ViewModel) и снова войти. На этот раз LiveData viewModel дает мне все сдвиги ранее сохранялся, как и ожидалось.

вот остальная часть кода:

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

почему я не получаю список сдвигов, которые я сохраняю в обратном вызове observe() сразу?

1 ответов


У меня была аналогичная проблема с использованием Dagger 2, которая была вызвана наличием разных экземпляров Dao, одного для обновления / вставки данных и другого экземпляра, предоставляющего LiveData для наблюдения. Как только я настроил Dagger для управления одноэлементным экземпляром Dao, я мог бы вставлять данные в фоновом режиме (в моем случае в Службе), наблюдая LiveData в моей деятельности - и вызывался бы обратный вызов onChange ().

Это сводится к тому, что экземпляр Dao должен быть тот же экземпляр, который вставляет / обновляет данные и предоставляет LiveData для наблюдения.