Я пытаюсь реализовать шаблон MVVM, используя компоненты архитектуры Google android, в то время как RX Java в NetworkBoundResource
. Однако мне трудно найти способ передать ответ об ошибке сетевого вызова на активность. Вот ссылка на оригинальный проект github .
. Я читал этот пост о " рефакторинге класса Google NetworkBoundResource для использования Rx Java вместо LiveData ", но до сих пор не ясно, как на самом деле решить проблему. был бы признателен, если бы вы могли направить меня к решению на основе кода для этого сценария для лучшего понимания.
ура!
GithubRepository:
@Singleton
public class GithubRepository {
private GithubDao githubDao;
private GithubApiService githubApiService;
public GithubRepository(GithubDao githubDao, GithubApiService githubApiService) {
this.githubDao = githubDao;
this.githubApiService = githubApiService;
}
public Observable<Resource<List<GithubEntity>>> getRepositories(Long page) {
return new NetworkBoundResource<List<GithubEntity>, GithubApiResponse>() {
@Override
protected void saveCallResult(@NonNull GithubApiResponse item) {
List<GithubEntity> repositories = item.getItems();
for (GithubEntity githubEntity : repositories) {
githubEntity.setPage(page);
githubEntity.setTotalPages(item.getTotalCount());
}
githubDao.insertRepositories(repositories);
}
@Override
protected boolean shouldFetch() {
return true;
}
@NonNull
@Override
protected Flowable<List<GithubEntity>> loadFromDb() {
List<GithubEntity> repositories = githubDao.getRepositoriesByPage(page);
return (repositories == null || repositories.isEmpty()) ?
Flowable.empty() : Flowable.just(repositories);
}
@NonNull
@Override
protected Observable<Resource<GithubApiResponse>> createCall() {
return githubApiService.fetchRepositories(QUERY_SORT, QUERY_ORDER, page)
.flatMap(response ->
Observable.just(response.isSuccessful()
? Resource.success(response.body())
: Resource.error("", new GithubApiResponse())));
}
}.getAsObservable();
}
}
.: ОБНОВЛЕНИЕ:. Итак, я вижу, что в NetworkBoundResource
the doOnError
и onErrorResumeNext
обрабатывают ответ об ошибке. но я не знаю, как получить этот ответ в деятельности. Мне трудно это понять.
NetworkBoundResource:
public abstract class NetworkBoundResource<ResultType, RequestType> {
private Observable<Resource<ResultType>> result;
@MainThread
protected NetworkBoundResource() {
Observable<Resource<ResultType>> source;
if (shouldFetch()) {
source = createCall()
.subscribeOn(Schedulers.io())
.doOnNext(apiResponse -> saveCallResult(processResponse(apiResponse)))
.flatMap(apiResponse -> loadFromDb().toObservable().map(Resource::success))
.doOnError(t -> onFetchFailed())
.onErrorResumeNext(t -> {
return loadFromDb()
.toObservable()
.map(data -> Resource.error(t.getMessage(), data));
})
.observeOn(AndroidSchedulers.mainThread());
} else {
source = loadFromDb()
.toObservable()
.map(Resource::success);
}
result = Observable.concat(
loadFromDb()
.toObservable()
.map(Resource::loading)
.take(1),
source
);
}
public Observable<Resource<ResultType>> getAsObservable() {return result;}
protected void onFetchFailed() {}
@WorkerThread
protected RequestType processResponse(Resource<RequestType> response) {return response.data;}
@WorkerThread
protected abstract void saveCallResult(@NonNull RequestType item);
@MainThread
protected abstract boolean shouldFetch();
@NonNull
@MainThread
protected abstract Flowable<ResultType> loadFromDb();
@NonNull
@MainThread
protected abstract Observable<Resource<RequestType>> createCall();
}
GithubListViewModel :
public class GithubListViewModel extends ViewModel {
private Long currentPage = 0l;
private GithubRepository repository;
private List<GithubEntity> repositories = new ArrayList<>();
private SingleLiveEvent<List<GithubEntity>> repoListLiveData = new SingleLiveEvent<>();
@Inject
public GithubListViewModel(GithubDao githubDao, GithubApiService githubApiService) {
repository = new GithubRepository(githubDao, githubApiService);
}
public void fetchRepositories() {
repository.getRepositories(++currentPage)
.subscribe(resource -> {
if(resource.isLoaded()) {
repositories.addAll(resource.data);
getRepositoryListLiveData().postValue(resource.data);
}
});
}
public List<GithubEntity> getRepositories() {
return repositories;
}
public SingleLiveEvent<List<GithubEntity>> getRepositoryListLiveData() {
return repoListLiveData;
}
public boolean isLastPage() {
return getRepositoryListLiveData().getValue() != null &&
!getRepositoryListLiveData().getValue().isEmpty() ?
getRepositoryListLiveData().getValue().get(0).isLastPage() :
false;
}
}
GithubActivity:
public class GithubListActivity extends AppCompatActivity implements RecyclerLayoutClickListener {
...
private void initialiseViewModel() {
githubListViewModel = ViewModelProviders.of(this, viewModelFactory).get(GithubListViewModel.class);
githubListViewModel.getRepositoryListLiveData().observe(this, repositories -> {
if(githubListAdapter.getItemCount() == 0) {
if(!repositories.isEmpty()) {
animateView(repositories);
} else displayEmptyView();
} else if(!repositories.isEmpty()) displayDataView(repositories);
});
}
...
githubListViewModel.fetchRepositories();
...
}