RxJava retrolambda
This is a example how to use RxJava and Retrolambda on Android.
You can see the complete example in GitHub
Java 8 introduced Lambdas Expressions, unfortunately Android does not support Java 8, so we are not able to take advantage of this with RxJava. Luckily there is a library called Retrolambda which backports lambdas to previous versions of Java. There is also a gradle plugin for Retrolambda that will allow the use of lambdas in an Android application.
In RxJava there are different elements:
1.BASIC(Observable)
2.ASYNCHRONOUS
3.SINGLES
4.SUBJECTS
5.MAP
6.DEBOUNCES
Basic
This method creates an Observable such that when an Observer subscribes, the onNext() of the Observer is immediately called with the argument provided to Observable.just(). The onCompleted() will then be called since the Observable has no other values to emit:
Observable<List<String>> listObservable = Observable.just(getColorList()); listObservable.subscribe(new Observer<List<String>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<String> colors) { mSimpleStringAdapter.setStrings(colors); } });
with lambda:
Observable<List<String>> listObservable = Observable.just(getColorList()); listObservable.subscribe( (List<String> colors)-> mSimpleStringAdapter.setStrings(colors), (error) -> {}, () -> {});
Asynchronous
If we use it with Observable.just(), mRestClient.getFavoriteTvShows() will be evaluated immediately and block the UI thread. Enter the Observable.fromCallable() method. It gives us two important things: * The code for creating the emitted value is not run until someone subscribes to the Observer. * The creation code can be run on a different thread.
Observable<List<String>> tvShowObservable = Observable.fromCallable(new Callable<List<String>>() { @Override public List<String> call() { return mRestClient.getFavoriteTvShows(); } }); mTvShowSubscription = tvShowObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( new Observer<List<String>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<String> tvShows) { displayTvShows(tvShows); } });
with lambda:
Observable<List<String>> tvShowObservable = Observable.fromCallable(() -> mRestClient.getFavoriteTvShows()); mTvShowSubscription = tvShowObservable .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( (List<String> tvShows) -> displayTvShows(tvShows), (error) -> {}, () -> {});
Singles
There’s a simpler version of an Observable called a Single. Singles work almost exactly the same as Observables. But instead of there being an onCompleted(), onNext(), and onError(), there are only two callbacks: * onSuccess() and onError().
Single<List<String>> tvShowSingle = Single.fromCallable(new Callable<List<String>>() { @Override public List<String> call() throws Exception { mRestClient.getFavoriteTvShows(); } }); mTvShowSubscription = tvShowSingle .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new SingleSubscriber<List<String>>() { @Override public void onSuccess(List<String> tvShows) { displayTvShows(tvShows); } @Override public void onError(Throwable error) { displayErrorMessage(); } });
with lambda:
Single<List<String>> tvShowSingle = Single.fromCallable(() -> mRestClient.getFavoriteTvShows()); mTvShowSubscription = tvShowSingle .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe((List<String> tvShows) -> displayTvShows(tvShows), (Throwable error) -> displayErrorMessage());
Subjects
Subjects are special objects that are both an Observable and an Observer. With a PublishSubject, as soon as you put something in one end of the pipe it immediately comes out the other.
PublishSubject<Integer> mCounterEmitter = PublishSubject.create(); mCounterEmitter.subscribe(new Observer<Integer>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Integer integer) { mCounterDisplay.setText(String.valueOf(integer)); } });
with lambda:
PublishSubject<Integer> mCounterEmitter = PublishSubject.create(); mCounterEmitter.subscribe( (Integer integer) -> mCounterDisplay.setText(String.valueOf(integer)), (Throwable e) ->{}, () -> { });
It increments a variable called mCounter. It calls onNext() on the mCounterEmitter with the new value of mCounter.
mCounter ++; mCounterEmitter.onNext(mCounter);
Map
It’s a function that takes in one value and outputs another value. Usually there is some relationship between value put in to the map and the value that is output.
Single.just(4).map(new Func1<Integer, String>() { @Override public String call(Integer integer) { return String.valueOf(integer); } }).subscribe(new SingleSubscriber<String>() { @Override public void onSuccess(String value) { mValueDisplay.setText(value); } @Override public void onError(Throwable error) { } });
with lambda:
Single.just(4).map((Integer integer) -> String.valueOf(integer)) .subscribe((String value) -> mValueDisplay.setText(value), (Throwable error) -> {});
Debounce
Everything together and a new concept: debounce. Let’s dive in. If you want to setup a PublishSubject such that it receives values the user types into a search box, fetches a list of suggestions based on that query, and then displays them.
mSearchResultsSubject = PublishSubject.create(); mTextWatchSubscription = mSearchResultsSubject .debounce(400, TimeUnit.MILLISECONDS) .observeOn(Schedulers.io()) .map(new Func1<String, List<String>>() { @Override public List<String> call(String s) { return mRestClient.searchForCity(s); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<String>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<String> cities) { handleSearchResults(cities); } }); });
with lambda:
mSearchResultsSubject = PublishSubject.create(); mTextWatchSubscription = mSearchResultsSubject .debounce(400, TimeUnit.MILLISECONDS) .observeOn(Schedulers.io()) .map( (String string) -> mRestClient.searchForCity(string)) .observeOn(AndroidSchedulers.mainThread()) .subscribe((List<String> cities) -> handleSearchResults(cities), (Throwable e) -> {}, () -> {});
Libraries
The project is setup using:
You can see the complete example in GitHub
As the above only gives a rough overview of rxjava example I’d strongly recommend checking out the following: