Android MVP - RxJava and retrofit - best approach

297 views Asked by At

I'm figuring out how to develop an Android app, using MVP, RxJava2 and retrofit.

In my presenter, here is the code:

public void loadData() {

    compositeDisposable.dataModelRepository.getDataList().subscribeOn(Schedulers.io())
            .observeOn(mainScheduler).subscribe(new Consumer<List<Data>>() {
        @Override
        public void accept(List<Data> dataList) throws Exception {
            if (!dataList.isEmpty())
                view.displayData(dataList);
            else
                view.displayEmpty();
        }
    }, new Consumer<Throwable>() {
        @Override
        public void accept(Throwable throwable) throws Exception {
            System.out.println(throwable.toString());
            view.displayError("boooom");
        }
    });
}

Retrofit interface has been defined in the following way:

@GET("/fooURL")
Single<List<Data>> getDataList();

And the repository is just

public Single<List<Data>> getDataList() {
    return retrofitApi.getDataList();
}

And it is working fine. Question is as follows: my intention is to fetch network data only when data is not available locally, in db.

Having this in mind, is it correct that schedulers are managed in the presenter? Or should they be managed in the Repository?

My guess is that presenter is the correct place, as it creates a thread so repository can do its stuff sequentially (fetch db, if nothing, then fetch network/cache; return data wherever it has been fetched), and when data is provided, notify the view inside the accept method of the Consumer.

Is it correct? Or should it be done in a different way?

Another point is: how can i test using Mockito the repository? The dataModelRepository.getDataList() method i mean? Not sure how to do any Assert for Single objects...

Thanks in advance!

1

There are 1 answers

1
Andrej Jurkin On

I suggest you to offload all business logic that is related to fetching, retrieving data to a central repository.

One way to achieve somewhat similar to what you have described is to use a concat operator.

Observable<List<Data>> getData() {
    return Observable
        .concat(localRepository.getData(), remoteRepository.getData())
        .first();
}

This will try to get data from your local repository first and if it has no data it will make a network request.

I assume your local and remote repositories will be observed on a new thread, but if you need to perform any action on the UI, simply subscribe on a main thread in your presenter.