Я работаю с API и комнатой, чтобы получить список техников по обслуживанию.
Я хочу сделать следующее:
- Запрос к
getAll()
из таблицы базы данных техников по обслуживанию . - Мгновенное отображение результатов для пользователей.
- Если он пуст или не удается получить результаты из базы данных, выполните вызов API, чтобы получить тот же список.
- Выполните вызов API, чтобы получить обновленный список техников по обслуживанию.
- Сохраните их в таблице базы данных.
- 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());
}
}
Есть идеи, как я могу улучшить этот код?