Почему liveata не уведомляет об активности при каждом обновлении данных

Я разрабатываю приложение с использованием шаблона MVVM, Retrofit и Rx Java. Приложение показывает филиалы библиотеки и имеющиеся там книги. Когда начинается деятельность, я начинаю загружать все ветки, а затем для каждой ветки загружаю книги. что-то вроде этого в ViewModel:

 private val branchBooksState: MutableLiveData<Pair<Branch,<List<Books>>> = MutableLiveData()

 private val libraryBranchesState: MutableLiveData<Outcome<List<Branch>>> = MutableLiveData()

 fun libraryBranchesState(): LiveData<Outcome<List<Branch>>> = libraryBranchesState

 fun branchBooksState(): LiveData<Pair<Library,<List<Books>>> = branchBooksState 
.....

fun loadLibraryBranchesAndThiereBooks(){

 compositeDisposable.add(  
            librariesInteractor.loadAllLibrarybranches()
                    .map {
                        libraryBranchesState.postValue(it)
                        it
                    }
                    .toObservable()
                    .flatMapIterable { it }
                    .flatMap {
                        librariesInteractor.loadBranchBooks(it.id).map { bookslist -> Pair(it, bookslist) }.toObservable()
                    }
                    .subscribe { pair ->
                         // there I get pair1, pair2, pair3, pair4 
                        branchBooksState.postValue(pair)
                    })}

В Activity я наблюдаю за живыми данными в viewModel и обновляю пользовательский интерфейс при изменении данных. Все работает нормально, но проблема в подписке, когда я получаю данные из параллельного запроса и использую branchBooksState.postValue (пара) для обновления liveata obj , пользовательский интерфейс не уведомляется для каждого состояния. Например, в подписке я публикую значения: пара 1 пара 2 пара 3 пара 4

но в деятельности я не уведомляю о каждом изменении. иногда я получаю уведомления с помощью: пара 1 пара 3 пара 4, а пара 2 отсутствует

.......
  private val libraryBranchesState = Observer<List<Branch>> {
    // display branches
}

private val branchBooksObserver = Observer<Pair<Branch ,<List<Book>>> {
    // problem here. I get pair1 , pair3 , pair4 
   // display branch books 
 
}

   override fun onCreate(savedInstanceState: Bundle?) {
    viewModel.libarayBooksState().observe(this, branchBooksObserver)
    viewModel.libraryBranchesState().observe(this, libraryBranchesObserver)}

 override fun onStart() {
    super.onStart()
     viewModel.loadLibraryBranchesAndThiereBooks()
}

Я борюсь с этим. Почему Activity не уведомляется о каждом изменении, происходящем в объекте liveata. Что не так с моим кодом? а как исправить?


person Abeer    schedule 25.07.2020    source источник


Ответы (1)


На самом деле с кодом нет ничего плохого;

Согласно документации: Если вы вызываете этот метод несколько раз до того, как основной поток выполнит опубликованную задачу, будет отправлено только последнее значение. (это относится к postValue)

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

Функцию можно изменить на

private val yourMutableList = mutableListOf<Pair<Library,<List<Books>>>()

fun loadLibraryBranchesAndThiereBooks(){

 compositeDisposable.add(  
            librariesInteractor.loadAllLibrarybranches()
                    .map {
                        libraryBranchesState.postValue(it)
                        it
                    }
                    .toObservable()
                    .flatMapIterable { it }
                    .flatMap {
                        librariesInteractor.loadBranchBooks(it.id).map { bookslist -> Pair(it, bookslist) }.toObservable()
                    }
                    .subscribe { pair ->
                        yourMutableList.add(pair)
                        branchBooksState.postValue(yourMutableList.toList())
                    })}
person Vishal Ambre    schedule 28.07.2020
comment
если я добавлю их в список, мне нужно дождаться добавления всех пар, а затем обновить пользовательский интерфейс. Не хочу ждать все пары. Я хочу обновить пользовательский интерфейс, как только получу значение пары в subscribe @Vishal Ambre - person Abeer; 29.07.2020
comment
Не стоит ждать получения всех пар, просто отправьте список, когда будет получена новая пара; - person Vishal Ambre; 29.07.2020