@Shadrindmitry

Как получить данные с room livedata и обновить их с помощью retrofit?

Данные хранятся с помощью Room. При старте активити создается слушатель observe, где с бд получаю данные. Эти данные мне нужно обновить с помощью Retrofit и перезаписать в бд. Как правильно это организовать? У меня проблема в том, что когда обновляются и перезаписываются данные, срабатывает слушатель observe и вновь начинает обновлять. Происходит зацикливание. Код:
metcastListViewModel.getMetcastListList().observe(MainActivity.this, new Observer<List<metcast>>() {
            @Override
            public void onChanged(@Nullable final List<metcast> metcasts) {
                    for (int i=0; i<metcasts.size(); i++) {
                        mMetcastAdapter.addItem(metcasts.get(i));

                        Call<metcast> Metcast = NetworkService.getInstance().getAPImetcast().getMetcast(
                                metcasts.get(i).getCity(), "token");                      
                        Metcast.enqueue(new Callback<metcast>() {
                            @Override
                            public void onResponse(Call<metcast> call, Response<metcast> response) {
                                if (response.isSuccessful()) {
                                    metcastListViewModel.updateByCity(response.body()); //Из-за этой строки вновь вызывается метод observe
                                    mMetcastAdapter.addItem(response.body());
                                }                     

                            @Override
                            public void onFailure(Call<metcast> call, Throwable t) {
                                mMetcastAdapter.addItems(metcasts);
                                Log.d("1337", "failure " + t);
                            }
                        });
                    }
                }

Можно не вставлять обновление данных в метод observe, но тогда я не знаю как получить данные и вставить их в retrofit для обновления
  • Вопрос задан
  • 895 просмотров
Решения вопроса 1
@visapps
Скорее всего вы неправильно поняли механизм работы LiveData. В LiveData из Room всегда будут приходить обновленные данные при их изменении. Стандартный паттерн: в данном случае нужно просто после получения данных из Retrofit вставить их в Room (через функцию insert в Dao с первичным ключом и OnConflictStrategy.Replace чтобы старые данные с одинаковым ключом заменялись на новые) и Room автоматически оповестит слушателей через LiveData об изменениях в данной таблице. Т.е. просто выносите логику осуществления запроса в Retrofit в отдельный метод в ViewModel, например refreshData(). При старте активити сразу вызываете refreshData(), затем подписываетесь на LiveData. В методе onChanged только отправляете адаптеру новые данные и все. Таким образом в onChanged сразу придут кешированные данные из БД (если они там есть), а затем когда Retrofit запрос выполнится и данные вставятся в БД, onChanged будет вызван еще раз и там будут обновленные данные. Заодно можно будет вызывать refreshData() также если пользователь захочет принудительно рефрешнуть данные. В onChanged у вас сейчас говнокод написан, если вы следуете современной архитектуре Android приложений (используя LiveData и ViewModel), запрос там с помощью Retrofit там делается обычно из репозитория, в крайнем случае из ViewModel, но никак не из активити.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@tiroman
Я возможно предложу банальщину, но если данные нужно обновить например один раз при старте то сделайте булеву переменную и меняйте ее состояние после первого обновления, чтобы второй раз не выполнялось
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы