I'm implementing network API with the combination of RxJava and Retrofit, and I use Realm as my database. I got it pretty much working but I'm wondering if it is the correct approach and flow of events. So, here is the RetrofitApiManager
.
public class RetrofitApiManager {
private static final String BASE_URL = "***";
private final ShopApi shopApi;
public RetrofitApiManager(OkHttpClient okHttpClient) {
// GSON INITIALIZATION
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl(BASE_URL)
.build();
shopApi = retrofit.create(ShopApi.class);
}
public Observable<RealmResults<Shop>> getShops() {
return shopApi.getShops()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(response -> {
Realm realm = Realm.getDefaultInstance();
realm.executeTransaction(realm1 ->
realm1.copyToRealmOrUpdate(response.shops));
realm.close();
})
.flatMap(response -> {
Realm realm = Realm.getDefaultInstance();
Observable<RealmResults<Shop>> results = realm.where(Shop.class)
.findAllAsync()
.asObservable()
.filter(RealmResults::isLoaded);
realm.close();
return results;
});
}
}
And here is the call to get RealmResults<Shop>
inside a Fragment
.
realm.where(Shop.class)
.findAllAsync()
.asObservable()
.filter(RealmResults::isLoaded)
.first()
.flatMap(shops ->
shops.isEmpty() ? retrofitApiManager.getShops() : Observable.just(shops))
.subscribe(
shops -> initRecyclerView(),
throwable -> processError(throwable));
Here are my questions:
Is it a correct approach to chain events like in the example above or should I manage them in a different way?
Is it OK to use
Realm
instance ingetShops()
method and close i there or would it be better to pass it as an argument and then manage it somehow? Although, this idea seems to be a bit problematic with threads and callingRealm.close()
always at the right time.