Как я могу улучшить этот код Rx Java с помощью Room and Retrofit? - PullRequest
0 голосов
/ 05 мая 2020

Я работаю с API и комнатой, чтобы получить список техников по обслуживанию.

Я хочу сделать следующее:

  1. Запрос к getAll() из таблицы базы данных техников по обслуживанию .
  2. Мгновенное отображение результатов для пользователей.
  3. Если он пуст или не удается получить результаты из базы данных, выполните вызов API, чтобы получить тот же список.
  4. Выполните вызов API, чтобы получить обновленный список техников по обслуживанию.
  5. Сохраните их в таблице базы данных.
  6. Refre sh Пользовательский интерфейс изменяется на основе последнего содержимого базы данных.

Вот то, что у меня есть, и оно работает. Но я думаю, что это можно улучшить:

  • Это похоже на ненужный вызов, если бы я мог как-то использовать Flowable .flatMap(ids -> techniciansDbRepository.getServiceTechnicians())
  • Я не могу использовать Flowable, так как filter(ServiceTechnician::isActive).toList(); никогда завершается, и я не получаю результат в subscribe().
  public void getServiceTechnicians() {
    disposables = RxUtil.initDisposables(disposables);

    Disposable disposable = techniciansDbRepository.getServiceTechnicians()
      .subscribeOn(Schedulers.io())
      .onErrorResumeNext(throwable -> techniciansApiRepository.getServiceTechnicians())
      .flatMap(serviceTechnicians -> techniciansApiRepository.getServiceTechnicians())
      .flatMap(techniciansDbRepository::insertAll)
      .flatMap(ids -> techniciansDbRepository.getServiceTechnicians())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(
        serviceTechnicians -> view.onServiceTechniciansLoaded(serviceTechnicians),
        view::handleError
      );

    disposables.add(disposable);
  }
public class ServiceTechniciansDbRepository implements ServiceTechniciansRepository {

  private final ServiceTechnicianDao dao;

  public ServiceTechniciansDbRepository(ServiceTechnicianDao dao) {
    this.dao = dao;
  }

  @Override public Single<List<ServiceTechnician>> getServiceTechnicians() {
    return dao.getAll()
      .flatMapPublisher(Flowable::fromIterable)
      .map(serviceTechnicianAndUser -> ServiceTechnicianMapper.convertToApiModel(
        serviceTechnicianAndUser.getServiceTechnician(),
        serviceTechnicianAndUser
      ))
      .filter(ServiceTechnician::isActive)
      .toList();
  }
}
@Dao public abstract class ServiceTechnicianDao implements BaseDao<ServiceTechnicianDb> {

  @Transaction
  @Query("SELECT * FROM service_technician")
  public  abstract Single<List<ServiceTechnicianAndUser>> getAll();

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  public abstract void insertUser(UserDb user);

}
public interface BaseDao<E> {

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  Single<Long> insert(E e);

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  Single<List<Long>> insert(List<E> list);

  @Update Single<Integer> update(E e);

  @Delete Single<Integer> delete(E e);

}
public class ServiceTechniciansApiRepository implements ServiceTechniciansRepository {

  private final ServiceTechnicianApi api;

  public ServiceTechniciansApiRepository(ServiceTechnicianApi api) {
    this.api = api;
  }

  @Override public Single<List<ServiceTechnician>> getServiceTechnicians() {
    return api.getServiceTechnicians()
      .subscribeOn(Schedulers.io());
  }

  @Override public Single<List<Long>> insertAll(List<ServiceTechnician> serviceTechnicians) {
    return Single.error(new CanNotBeUsedWithApiException());
  }
}

Есть идеи, как я могу улучшить этот код?

...