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 для наблюдения.