1

I am super junior in RxJava and I may need to find a better approach if there is a better way to do it.

I am working on a legacy Loader code and I want to replace it by RxJava. I have following in my original code:

public class CurrentBookingLoaderManager extends AsyncTaskLoader<Booking> {
    ...

    @Override
    public Booking loadInBackground() {
        try {
            return createPendingBookingObserver().blockingGet(); // Gets last Booking from back-end
        } catch (Exception e) {
            Logger.logCaughtException(e);
            return loadPendingBookingFromDB();
        }
    }

    private Single<Booking> createPendingBookingObserver() {...}

    private Booking loadPendingBookingFromDB() {...}
}

So, My Presenter class is looking for latest Booking object in order to direct user to next screen (based on status of Booking).

final class Presenter {
    void findLatestBooking() {
        CurrentBookingLoaderManager.newInstance(mContext)
                .getPendingBooking(mActivity, new CurrentBookingLoaderManager.OnPendingBooking() {
                    @Override
                    public void found(Booking booking) {
                        ...
                    }
                });
    }
}

Back to CurrentBookingLoaderManager, I created an interface and few methods in order to refactor the functionality of loadInBackground() in Rx way.

    public interface OnPendingBooking {
        void found(Booking booking);
    }

    public void getPendingBooking(final MyActivity activity, final OnPendingBooking callback) {
        CurrentBookingLoaderManager.newInstance(activity)
                .createPendingBookingObserver()
                .compose(activity.<Booking>asyncCallWithinLifecycle())
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Booking>() {
                    @Override
                    public void accept(Booking booking) throws Exception {
                        callback.found(booking);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        loadPendingBookingFromDB(activity, callback);
                    }
                });
    }

    private void loadPendingBookingFromDB(final MyActivity activity, final OnPendingBooking callback) {
        Single.fromCallable(new Callable<Booking>() {
            @Override
            public Booking call() throws Exception {
                return loadPendingBookingFromDB();
            }
        })
                .compose(activity.<Booking>asyncCallWithinLifecycle())
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Booking>() {
                    @Override
                    public void accept(Booking booking) throws Exception {
                        callback.found(booking);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Exception {
                        callback.found(null);
                    }
                });
    }

What makes me feel this is not right approach is having many many lines by using RxJava while Rx normally reduces number of lines of code. Might there be a better way to do it?

This code works fine based on my tests.

halfer
  • 19,824
  • 17
  • 99
  • 186
Hesam
  • 52,260
  • 74
  • 224
  • 365
  • Rxjava 1 or 2? there is a little bit difference in classes in both. – Saurabh Jan 30 '17 at 21:57
  • @Saurabh RxJava 2 actually, thanks for asking :) I just updated my question. – Hesam Jan 30 '17 at 21:59
  • 1
    the only thing you could improve is using `subscribeOn(Schedulers.io())` , instead of creating a new thread everytime. rest looks fine to me. :) – Saurabh Jan 30 '17 at 22:03

1 Answers1

1
  1. RetroLambda
  2. SqlBrite instead of AsyncTaskLoader
  3. If possible Realm instead of sqlite.
  4. subscribeOn(Schedulers.newThread()) -> subscribeOn(Schedulers.io()) (no need to create new thread each time)
  5. And

    Observable
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    

Can be replaced with

public class RxUtil {

    public static <T> Observable.Transformer<T, T> applySchedulers() {
        return observable -> observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}

and

Observable
   .compose(RxUtil::applySchedulers)
Kishan Viramgama
  • 893
  • 1
  • 11
  • 23
Divers
  • 9,531
  • 7
  • 45
  • 88