Я создаю автономное первое приложение с настройкой базы данных в качестве единственного источника правды.Я использую Room для упрощения обработки базы данных и LiveData для упрощения наблюдаемых шаблонов данных.
Я также использую Retrofit для выполнения любых сетевых вызовов, необходимых для заполнения базы данных новыми данными.
Iнастроил наблюдателя в моем фрагменте следующим образом:
private void setUpObserver() {
tfViewModel = ViewModelProviders.of(getActivity()).get(TFViewModel.class);
tfViewModel.getAllPosts().observe(getActivity(),
newPosts -> {
if (newPosts != null && newPosts.size() > 0) {
lottieAnimationView.setVisibility(View.INVISIBLE);
mPostsAdapter.updateItems(newPosts);
}
});
tfViewModel.fetchNextData(currentPage);
}
Когда мое приложение запускается впервые, я намеренно обрезаю каждую таблицу в моей базе данных, используя обратные вызовы Room, чтобы каждый раз получать новые данные.(Для тестирования. Это превосходит опыт работы в автономном режиме и не должен выполняться в рабочей среде.)
В любом случае, поэтому при первом запуске он вызывает метод fetchNextData
модели представления, который, в свою очередь, запрашивает репозиторий.для извлечения данных.
Вот мой ViewModel:
public class TFViewModel extends AndroidViewModel {
private TFRepository mRepository;
private LiveData<List<Post>> mPostList;
public TFViewModel(Application application) {
super(application);
mRepository = new TFRepository(application);
mPostList = mRepository.getAllPosts();
}
public LiveData<List<Post>> getAllPosts() {
return mPostList;
}
public void fetchNextData(int page) {
mRepository.fetchNextPosts(page);
}
}
В хранилище я использую свои DAO для вставки сообщений в базу данных.Чтобы получить новые данные, я использую класс обслуживания, чтобы получить новые данные для меня.Когда вызов извлечения возвращается, я использую AsyncTask, чтобы вставить новые сообщения в мою базу данных.(Детали опущены для краткости):
public class TFRepository {
private PostDao postDao;
private LiveData<List<Post>> postList;
private RetrofitSingleton retrofitSingleton;
public TFRepository(Application application) {
TFRoomDatabase db = TFRoomDatabase.getDatabase(application);
postDao = db.postDao();
retrofitSingleton = RetrofitSingleton.getInstance(application.getApplicationContext());
postList = postDao.getAllPosts();
}
public LiveData<List<Post>> getAllPosts() {
return postList;
}
public void fetchNextPosts(int page) {
getPostList(page);
}
private void getPostList(int page) {
APICaller.getInstance(retrofitSingleton).getFeed(page,
new NetworkResponseListener<BaseResponse<FeedResponse>>() {
@Override
public void onResponseReceived(BaseResponse<FeedResponse> feedResponseBaseResponse) {
if (feedResponseBaseResponse == null) return;
List<Post> posts = feedResponseBaseResponse.getData().getPosts();
new insertAllPostsAsyncTask(postDao).execute(posts);
}
@Override
public void onError(String errorMessage) {
}
});
}
}
Наблюдатель, который я настроил в своем фрагменте , получает пустой список в первый раз .Вызов API возвращается с первой страницей сообщений и получает 10 сообщений во второй раз. Представление всплывающее.Все хорошо.
Проблема: Когда пользователь прокручивает страницу вниз, Fragment просит ViewModel получить больше данных.ViewModel просит хранилище извлечь новые данные.Вызов Retrofit выполняется и возвращается с новыми данными .Он вставлен в базу данных. НО НАБЛЮДАТЕЛЬ НЕ УВЕДОМЛЕН. Чего мне не хватает?
ПРИМЕЧАНИЕ. Я не хочу использовать MutableLiveData
, так как я хочу поддерживать БД какединственный источник правды.Кроме того, поскольку в документации указано, что LiveData уведомляется всякий раз, когда базовая БД изменяет , моя реализация должна работать с LiveData.