0% found this document useful (0 votes)
72 views

Using RxJava 2 - Tutorial - Vogel

Uploaded by

Refat Nafiu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views

Using RxJava 2 - Tutorial - Vogel

Uploaded by

Refat Nafiu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

7/9/2018 Using RxJava 2 - Tutorial

Tutorials (http://www.vogella.com/tutorials/) Training (http://www.vogella.com/training/) Consulting (http://www.vogella.com/consulting/)


Search

(http://www.vogella.com)

Using RxJava 2 - Tutorial


Downloads (http://www.vogella.com/downloads/) Books (http://www.vogella.com/books/) Company (http://www.vogella.com/company/)
Online Traini
(https://learn.vogel
Lars Vogel, Simon
Donate (http://www.vogella.com/support.html) Scholz
Contact (c) 2017 vogella GmbH – Version 1.1, 
us (http://www.vogella.com/contact.html)
04.07.2017 QUICK LINKS
15 OCT - RC
Table of Contents Training
(http://www.vo
1. Using reactive programming with RxJava 2.0
vogella Traini
2. Build blocks for RxJava
(http://www.vo
3. RxJava example vogella Books
4. Creating Observables, subscribing to them and disposing them (http://www.vo

5. Caching values of completed observables


SHARE
6. Conversion between types
7. RxAndroid
8. Exercise: First steps with RxJava and RxAndroid
9. Testing RxJava Observables and Subscriptions
10. Exercise: Writing unit tests for RxJava
11. About this website
12. RxJava resources
Appendix A: Copyright and License

This tutorial contains notes about RxJava 2.0.

1. Using reactive programming with


RxJava 2.0
1.1. What is RxJava and reactive programming
In reactive programming the consumer reacts to the data as it
comes in. This is the reason why asynchronous programming is also
called reactive programming. Reactive programming allows to
propagates event changes to registered observers.

Reactivex (http://reactivex.io/) is a project which provides


implementations for this concept for different programming
languages. It describes itself as:

“ The Observer pattern done right. ReactiveX is a


combination of the best ideas from the Observer
pattern, the Iterator pattern, and functional
programming.

http://www.vogella.com/tutorials/RxJava/article.html 1/32
7/9/2018 Using RxJava 2 - Tutorial

RxJava (https://github.com/ReactiveX/RxJava) is the Java implementation


of this concept. RxJava is published under the Apache 2.0 license.
RxJava provides Java API for asynchronous programming with
observable streams. Online Traini
(https://learn.vogel

2. Build blocks for RxJava QUICK LINKS


15 OCT - RC
The build blocks for RxJava code are the following:
Training
(http://www.vo
observables representing sources of data
vogella Traini
subscribers (or observers) listening to the observables (http://www.vo
vogella Books
a set of methods for modifying and composing the data (http://www.vo

An observable emits items; a subscriber consumes those items. SHARE

2.1. Observables
Observables are the sources for the data. Usually they start
providing data once a subscriber starts listening. An observable
may emit any number of items (including zero items). It can
terminate either successfully or with an error. Sources may never
terminate, for example, an observable for a button click can
potentially produce an infinite stream of events.

2.2. Subscribers
A observable can have any number of subscribers. If a new item is
emitted from the observable, the onNext() method is called on
each subscriber. If the observable finishes its data flow successful,
the onComplete() method is called on each subscriber. Similar, if
the observable finishes its data flow with an error, the onError()
method is called on each subscriber.

3. RxJava example
A very simple example written as JUnit4 test is the following:

http://www.vogella.com/tutorials/RxJava/article.html 2/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import org.junit.Test;
Online Traini
import io.reactivex.Observable; (https://learn.vogel

import static junit.framework.Assert.assertTrue;


QUICK LINKS
15 OCT - RC
public class RxJavaUnitTest {
Training
String result="";
(http://www.vo

// Simple subscription to a fix value vogella Traini


@Test (http://www.vo
public void returnAValue(){ vogella Books
result = "";
(http://www.vo
Observable<String> observer = Observable.just("Hello");
// provides datea
observer.subscribe(s -> result=s); // Callable as SHARE
subscriber
assertTrue(result.equals("Hello"));
}
}

3.1. Why doing asynchronous programming


Reactive programming provides a simple way of asynchronous
programming. This allows to simplify the asynchronously
processing of potential long running operations. It also provides a
defined way of handling multiple events, errors and termination of
the event stream. Reactive programming provides also a simplified
way of running different tasks in different threads. For example,
widgets in SWT and Android have to be updated from the UI thread
and reactive programming provides ways to run observables and
subscribers in different threads.

It is also possible to convert the stream before its received by the


observers. And you can chain operations, e.g., if a API call depends
on the call of another API Last but not least, reactive programming
reduces the need for state variables, which can be the source of
errors.

3.2. Adding RxJava 2 to a Java project


As of this writing the version 2.1.1 is currently the released one.
Replace the version with your desired version.

To use RxJava in a Gradle build, add the following as dependency.

GROOVY
compile group: 'io.reactivex.rxjava2', name: 'rxjava', version:
'2.1.1'

For Maven, you can add RxJava via the following snippet.

http://www.vogella.com/tutorials/RxJava/article.html 3/32
7/9/2018 Using RxJava 2 - Tutorial

XML
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.0.4</version> Online Traini
</dependency> (https://learn.vogel

For OSGi environments, e.g., Eclipse RCP development, QUICK LINKS

https://dl.bintray.com/simon-scholz/RxJava-OSGi/ can be used as p2 15 OCT - RC


Training
update site.
(http://www.vo
vogella Traini
4. Creating Observables, subscribing to (http://www.vo

them and disposing them vogella Books


(http://www.vo

4.1. Creating observables


SHARE
You can create different types of observables.

Table 1. Obervable types

Type Description

Flowable<T> Emits 0 or n items and


terminates with an success or
an error event. Supports
backpressure, which allows to
control how fast a source emits
items.

Observable<T> Emits 0 or n items and


terminates with an success or
an error event.

Single<T> Emits either a single item or an


error event. The reactive
version of a method call.

Maybe<T> Succeeds with an item, or no


item, or errors. The reactive
version of an Optional.

Completable Either completes with an


success or with an error event.
It never emits items. The
reactive version of a Runnable.

An example for the usage of Flowable , is when you process touch


events. You cannot control the user who is doing these touch events,
but you can tell the source to emit the events on a slower rate in
case you cannot processes them at the rate the user produces them.

The following shows an example for the creation of an observable.

http://www.vogella.com/tutorials/RxJava/article.html 4/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
Observable<Todo> todoObservable = Observable.create(new
ObservableOnSubscribe<Todo>() {
@Override
public void subscribe(ObservableEmitter<Todo> Online Traini
emitter) throws Exception { (https://learn.vogel
try {
List<Todo> todos =
RxJavaUnitTest.this.getTodos(); QUICK LINKS
for (Todo todo : todos) { 15 OCT - RC
emitter.onNext(todo);
Training
}
(http://www.vo
emitter.onComplete();
} catch (Exception e) { vogella Traini
emitter.onError(e); (http://www.vo
} vogella Books
}
(http://www.vo
});

SHARE
Using lambdas, the same statement can be expressed as:

JAVA
Observable<Todo> todoObservable = Observable.create(emitter ->
{
try {
List<Todo> todos = getTodos();
for (Todo todo : todos) {
emitter.onNext(todo);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
});

The following is an example for a Maybe .

JAVA
Maybe<List<Todo>> todoMaybe = Maybe.create(emitter -> {
try {
List<Todo> todos = getTodos();
if(todos != null && !todos.isEmpty()) {
emitter.onSuccess(todos); 1

} else {
emitter.onComplete(); 2

}
} catch (Exception e) {
emitter.onError(e); 3

}
});

1 java.util.Optional has a value

2 java.util.Optional contains no value → null

3 An error occurred

4.2. Convenience methods to create observables


RxJava provides several convenience methods to create observables

Observable.just("Hello") - Allows to create an observable as


wrapper around other data types

http://www.vogella.com/tutorials/RxJava/article.html 5/32
7/9/2018 Using RxJava 2 - Tutorial

Observable.fromIterable() - takes an
java.lang.Iterable<T> and emits their values in their order
in the data structure
Online Traini
Observable.fromArray() - takes an array and emits their (https://learn.vogel
values in their order in the data structure
QUICK LINKS
Observable.fromCallable() - Allows to create an observable
15 OCT - RC
for a java.util.concurrent.Callable<V> Training
Observable.fromFuture() - Allows to create an observable for (http://www.vo
vogella Traini
a java.util.concurrent.Future
(http://www.vo
Observable.interval() - An observable that emits Long vogella Books
objects in a given interval (http://www.vo

Similar methods exists for the other data types, e.g., SHARE
* Flowable.just() , Maybe.just() and Single.just .

4.3. Subscribing in RxJava


To receive the data emitted from an observable you need to
subscribe to it. observables offer a large variety of subscribe
methods.

JAVA
Observable<Todo> todoObservable = Observable.create(emitter ->
{ ... });

// Simply subscribe with a io.reactivex.functions.Consumer<T>,


which will be informed onNext()
Disposable disposable = todoObservable.subscribe(t ->
System.out.print(t));

// Dispose the subscription when not interested in the emitted


data any more
disposable.dispose();

// Also handle the error case with a second


io.reactivex.functions.Consumer<T>
Disposable subscribe = todoObservable.subscribe(t ->
System.out.print(t), e -> e.printStackTrace());

There is also a subscribeWith method on observable instances,


which can be used like this:

JAVA
DisposableObserver<Todo> disposableObserver =
todoObservable.subscribeWith(new DisposableObserver<Todo>() {

@Override
public void onNext(Todo t) {
}

@Override
public void onError(Throwable e) {
}

@Override
public void onComplete() {
}
});

http://www.vogella.com/tutorials/RxJava/article.html 6/32
7/9/2018 Using RxJava 2 - Tutorial

4.4. Disposing subscriptions and using


Online Traini
CompositeDisposable (https://learn.vogel

When listers or subscribers are attached they usually are not


QUICK LINKS
supposed to listen eternally.
15 OCT - RC
So it could happen that due to some state change the event being Training
(http://www.vo
emitted by an observable might be not interesting any more.
vogella Traini
JAVA
(http://www.vo
import io.reactivex.Single; vogella Books
import io.reactivex.disposables.Disposable;
(http://www.vo
import io.reactivex.observers.DisposableSingleObserver;

Single<List<Todo>> todosSingle = getTodos(); SHARE

Disposable disposable = todosSingle.subscribeWith(new


DisposableSingleObserver<List<Todo>>() {

@Override
public void onSuccess(List<Todo> todos) {
// work with the resulting todos
}

@Override
public void onError(Throwable e) {
// handle the error case
}
});

// continue working and dispose when value of the Single is not


interesting any more
disposable.dispose();

The Single class and other observable classes offer

 different subscribe methods, which return a


Disposable object.

When working with multiple subscriptions, which may become


obsolete due to the same state change using a
CompositeDisposable is pretty handy to dispose a collection of
subscriptions.

http://www.vogella.com/tutorials/RxJava/article.html 7/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
import io.reactivex.Single;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableSingleObserver;
import io.reactivex.disposables.CompositeDisposable; Online Traini
(https://learn.vogel
CompositeDisposable compositeDisposable = new
CompositeDisposable();
QUICK LINKS
Single<List<Todo>> todosSingle = getTodos(); 15 OCT - RC
Training
Single<Happiness> happiness = getHappiness();
(http://www.vo

compositeDisposable.add(todosSingle.subscribeWith(new vogella Traini


DisposableSingleObserver<List<Todo>>() { (http://www.vo
vogella Books
@Override
(http://www.vo
public void onSuccess(List<Todo> todos) {
// work with the resulting todos
} SHARE

@Override
public void onError(Throwable e) {
// handle the error case
}
}));

compositeDisposable.add(happiness.subscribeWith(new
DisposableSingleObserver<Happiness>() {

@Override
public void onSuccess(Happiness happiness) {
// celebrate the happiness :-D
}

@Override
public void onError(Throwable e) {
System.err.println("Don't worry, be happy! :-P");
}
}));

// continue working and dispose all subscriptions when the


values from the Single objects are not interesting any more
compositeDisposable.dispose();

5. Caching values of completed


observables
When working with observables doing async calls on every
subscription on an observable is often not necessary.

It likely happens that observables are passed around in the


application, without the need to do an such an expensive call all the
time a subscription is added.

The following code does the expensive web query 4 times, even
though doing this once would be fine, since the same Todo objects
should be shown, but only in different ways.

http://www.vogella.com/tutorials/RxJava/article.html 8/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
Single<List<Todo>> todosSingle = Single.create(emitter -> {
Thread thread = new Thread(() -> {
try {
List<Todo> todosFromWeb = // query a webservice Online Traini
(https://learn.vogel
System.out.println("Called 4 times!");

emitter.onSuccess(todosFromWeb); QUICK LINKS


} catch (Exception e) { 15 OCT - RC
emitter.onError(e);
Training
}
(http://www.vo
});
thread.start(); vogella Traini
}); (http://www.vo
vogella Books
todosSingle.subscribe(... " Show todos times in a bar chart "
(http://www.vo
...);

showTodosInATable(todosSingle); SHARE

todosSingle.subscribe(... " Show todos in gant diagram " ...);

anotherMethodThatsSupposedToSubscribeTheSameSingle(todosSingle)
;

The next code snippet makes use of the cache method, so that the
Single instance keeps its result, once it was successful for the first
time.

JAVA
Single<List<Todo>> todosSingle = Single.create(emitter -> {
Thread thread = new Thread(() -> {
try {
List<Todo> todosFromWeb = // query a webservice

System.out.println("I am only called once!");

emitter.onSuccess(todosFromWeb);
} catch (Exception e) {
emitter.onError(e);
}
});
thread.start();
});

// cache the result of the single, so that the web query is


only done once
Single<List<Todo>> cachedSingle = todosSingle.cache();

cachedSingle.subscribe(... " Show todos times in a bar chart "


...);

showTodosInATable(cachedSingle);

cachedSingle.subscribe(... " Show todos in gant diagram " ...);

anotherMethodThatsSupposedToSubscribeTheSameSingle(cachedSingle
);

6. Conversion between types


It is easy to convert between different RxJava types.

Table 2. Conversion between types

http://www.vogella.com/tutorials/RxJava/article.html 9/32
7/9/2018 Using RxJava 2 - Tutorial

From / Flowab Observ Maybe Single Comple


To le able table

Online Traini
Flowab toObser reduce() scan() ignoreEl (https://learn.vogel
le vable() element element ements()
At() At() QUICK LINKS
firstEle first()/fi 15 OCT - RC
ment() rstOrErr Training
lastEle or() (http://www.vo

ment() last()/las vogella Traini


(http://www.vo
singleEl tOrErro
vogella Books
ement() r()
(http://www.vo
single()/
singleOr SHARE
Error()
all()/any
()/count(
)
(and
more…)

Observ toFlowa reduce() scan() ignoreEl


able ble() element element ements()
At() At()
firstEle first()/fi
ment() rstOrErr
lastEle or()
ment() last()/las
singleEl tOrErro
ement() r()
single()/
singleOr
Error()
all()/any
()/count(
)
(and
more…)

Maybe toFlowa toObser toSingle toCompl


ble() vable() () etable()
sequenc
eEqual()

Single toFlowa toObser toMayb toCompl


ble() vable() e() etable()

http://www.vogella.com/tutorials/RxJava/article.html 10/32
7/9/2018 Using RxJava 2 - Tutorial

From / Flowab Observ Maybe Single Comple


To le able table

Online Traini
Comple toFlowa toObser toMayb toSingle (https://learn.vogel
table ble() vable() e() ()
toSingle QUICK LINKS
Default( 15 OCT - RC
) Training
(http://www.vo
vogella Traini
7. RxAndroid (http://www.vo
vogella Books
7.1. Using RxAndroid (http://www.vo

RxAndroid is an extension to RxJava. It providers a scheduler to run


SHARE
code in the main thread of Android. It also provides the ability to
create a scheduler that runs on a Android handler class. With this
schedulers, you can define an observable which does its work in a
background thread, and post our results to the main thread. This
allows for example to replace a AsyncTask implementations which
RxJava.

To use RxJava in Android add the following dependency to your


build.gradle file.

GRADLE
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.8'

For example you can define a long running operation via the
following observable.

JAVA
final Observable<Integer> serverDownloadObservable =
Observable.create(emitter -> {
SystemClock.sleep(1000); // simulate delay
emitter.onNext(5);
emitter.onComplete();
});

You can now subscribe to this observable. This triggers its execution
and provide the subscribe with the required information.

For example, lets assume you assign this to a button.

JAVA
serverDownloadObservable.

observeOn(AndroidSchedulers.mainThread()). 1

subscribeOn(Schedulers.io()). 2

subscribe(integer -> {
updateTheUserInterface(integer); //
this methods updates the ui
view.setEnabled(true); // enables
it again
});
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());

http://www.vogella.com/tutorials/RxJava/article.html 11/32
7/9/2018 Using RxJava 2 - Tutorial

1 The subscriber observes in the main thread


2 Observable is called outside the main thread
Online Traini
As we are only interested in the final result, we could also use a (https://learn.vogel
Single .
QUICK LINKS
JAVA 15 OCT - RC
Subscription subscription = Single.create(new
Single.OnSubscribe() { Training
@Override (http://www.vo
public void call(SingleSubscriber singleSubscriber) vogella Traini
{
(http://www.vo
String result = doSomeLongRunningStuff();
singleSubscriber.onSuccess(value);
vogella Books
} (http://www.vo
})
.subscribeOn(Schedulers.io()) SHARE
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1() {
@Override
public void call(String value) {
// onSuccess
updateTheUserInterface(); // this methods
updates the ui
}
}, new Action1() {
@Override
public void call(Throwable throwable) {
// handle onError
}
});

7.2. Unsubscribe to avoid memory leaks


Observable.subscribe() returns a Subscription (if you are
using a Flowable) or a Disposable object. To prevent a possible
(temporary) memory leak, unsubscribe from your observables in
the`onStop()` method of the activity or fragment. For example, for a
Disposable object you could do the following:

JAVA
@Override
protected void onDestroy() {
super.onDestroy();
if (bookSubscription != null &&
!bookSubscription.isDisposed()) {
bookSubscription.dispose();
}
}

8. Exercise: First steps with RxJava and


RxAndroid
Create a new project with the
com.vogella.android.rxjava.simple top level package name.

8.1. Gradle dependencies


Add the following dependencies to your app/build.gradle file.

http://www.vogella.com/tutorials/RxJava/article.html 12/32
7/9/2018 Using RxJava 2 - Tutorial

GROOVY
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.8'
compile 'com.squareup.okhttp:okhttp:2.5.0' Online Traini
testCompile 'junit:junit:4.12' (https://learn.vogel

Also enable the usage of Java 8 in your app/build.gradle file. QUICK LINKS
15 OCT - RC
GROOVY Training
android {
(http://www.vo
// more stuff
compileOptions { vogella Traini
sourceCompatibility JavaVersion.VERSION_1_8 (http://www.vo
targetCompatibility JavaVersion.VERSION_1_8 vogella Books
}
(http://www.vo
}

SHARE
8.2. Create activities
Change your main layout file to the following.

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>

<Button
android:id="@+id/first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="First"
/>

<Button
android:id="@+id/second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Second"

/>

<Button
android:id="@+id/third"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Third"

/>
</LinearLayout>

Create three activities:

RxJavaSimpleActivity

BooksActivity

ColorsActivity

http://www.vogella.com/tutorials/RxJava/article.html 13/32
7/9/2018 Using RxJava 2 - Tutorial

Create the activity_rxjavasimple.xml layout file.

XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Online Traini
(https://learn.vogel
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" QUICK LINKS
>
15 OCT - RC
<Button Training
android:id="@+id/button" (http://www.vo
android:layout_width="wrap_content" vogella Traini
android:layout_height="wrap_content"
(http://www.vo
android:text="Server"
/> vogella Books
<Button (http://www.vo
android:id="@+id/toastbutton"
android:layout_width="wrap_content" SHARE
android:layout_height="wrap_content"
android:text="Toast"
android:onClick="onClick"
/>

<TextView
android:id="@+id/resultView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Result"
/>
</LinearLayout>

activity_colors.xml

In RxJavaSimpleActivity create a observable which simulates a


long running operation (10 secs) and afterwards returns the
number 5. Subscribe to it via a button click, disable the button

http://www.vogella.com/tutorials/RxJava/article.html 14/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.os.Bundle;
import android.os.SystemClock; Online Traini
import android.support.v7.app.AppCompatActivity; (https://learn.vogel
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView; QUICK LINKS
import android.widget.Toast; 15 OCT - RC
Training
import io.reactivex.Observable;
(http://www.vo
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable; vogella Traini
import io.reactivex.disposables.Disposable; (http://www.vo
import io.reactivex.schedulers.Schedulers; vogella Books
(http://www.vo

public class RxJavaSimpleActivity extends AppCompatActivity {


SHARE
RecyclerView colorListView;
SimpleStringAdapter simpleStringAdapter;
CompositeDisposable disposable = new CompositeDisposable();
public int value =0;

final Observable<Integer> serverDownloadObservable =


Observable.create(emitter -> {
SystemClock.sleep(10000); // simulate delay
emitter.onNext(5);
emitter.onComplete();
});

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rxjavasimple);
View view = findViewById(R.id.button);
view.setOnClickListener(v -> {
v.setEnabled(false); // disables the button until
execution has finished
Disposable subscribe = serverDownloadObservable.
observeOn(AndroidSchedulers.mainThread()).
subscribeOn(Schedulers.io()).
subscribe(integer -> {
updateTheUserInterface(integer); //
this methods updates the ui
v.setEnabled(true); // enables it again
});
disposable.add(subscribe);
});
}

private void updateTheUserInterface(int integer) {


TextView view = (TextView)
findViewById(R.id.resultView);
view.setText(String.valueOf(integer));
}

@Override
protected void onStop() {
super.onStop();
if (disposable!=null && !disposable.isDisposed()) {
disposable.dispose();
}
}

public void onClick(View view) {


Toast.makeText(this, "Still active " + value++,
Toast.LENGTH_SHORT).show();

http://www.vogella.com/tutorials/RxJava/article.html 15/32
7/9/2018 Using RxJava 2 - Tutorial

}
}

Create an adapter for a recycler view. Online Traini


(https://learn.vogel

QUICK LINKS
15 OCT - RC
Training
(http://www.vo
vogella Traini
(http://www.vo
vogella Books
(http://www.vo

SHARE

http://www.vogella.com/tutorials/RxJava/article.html 16/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.content.Context;
import android.support.v7.widget.RecyclerView; Online Traini
import android.view.LayoutInflater; (https://learn.vogel
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; QUICK LINKS
import android.widget.Toast; 15 OCT - RC
Training
import java.util.ArrayList;
(http://www.vo
import java.util.List;
vogella Traini
/** (http://www.vo
* Adapter used to map a String to a text view. vogella Books
*/
(http://www.vo
public class SimpleStringAdapter extends
RecyclerView.Adapter<SimpleStringAdapter.ViewHolder> {
SHARE
private final Context mContext;
private final List<String> mStrings = new ArrayList<>();

public SimpleStringAdapter(Context context) {


mContext = context;
}

public void setStrings(List<String> newStrings) {


mStrings.clear();
mStrings.addAll(newStrings);
notifyDataSetChanged();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int
viewType) {
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.strin
g_list_item, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, final int
position) {
holder.colorTextView.setText(mStrings.get(position));
holder.itemView.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext,
mStrings.get(position), Toast.LENGTH_SHORT).show();
}
});
}

@Override
public int getItemCount() {
return mStrings.size();
}

public static class ViewHolder extends


RecyclerView.ViewHolder {

public final TextView colorTextView;

public ViewHolder(View view) {


super(view);
colorTextView = (TextView)
view.findViewById(R.id.color_display);

http://www.vogella.com/tutorials/RxJava/article.html 17/32
7/9/2018 Using RxJava 2 - Tutorial

}
}
}

Online Traini
Implement ColorsActivity which uses a observable to receive a (https://learn.vogel

list of colors.
QUICK LINKS
Create the activity_colors.xml layout file. 15 OCT - RC
Training
XML (http://www.vo
<?xml version="1.0" encoding="utf-8"?>
vogella Traini
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" (http://www.vo
android:layout_width="match_parent" vogella Books
android:layout_height="match_parent" (http://www.vo
>
<android.support.v7.widget.RecyclerView
android:id="@+id/color_list"
SHARE
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>

http://www.vogella.com/tutorials/RxJava/article.html 18/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; Online Traini
import android.support.v7.widget.LinearLayoutManager; (https://learn.vogel
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList; QUICK LINKS


import java.util.List; 15 OCT - RC
Training
import io.reactivex.Observable;
(http://www.vo
import io.reactivex.disposables.Disposable;
vogella Traini
(http://www.vo
public class ColorsActivity extends AppCompatActivity { vogella Books
(http://www.vo
RecyclerView colorListView;
SimpleStringAdapter simpleStringAdapter;
private Disposable disposable; SHARE

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
configureLayout();
createObservable();
}

private void createObservable() {


Observable<List<String>> listObservable =
Observable.just(getColorList());
disposable = listObservable.subscribe(colors ->
simpleStringAdapter.setStrings(colors));

private void configureLayout() {


setContentView(R.layout.activity_colors);
colorListView = (RecyclerView)
findViewById(R.id.color_list);
colorListView.setLayoutManager(new
LinearLayoutManager(this));
simpleStringAdapter = new SimpleStringAdapter(this);
colorListView.setAdapter(simpleStringAdapter);
}

private static List<String> getColorList() {


ArrayList<String> colors = new ArrayList<>();
colors.add("red");
colors.add("green");
colors.add("blue");
colors.add("pink");
colors.add("brown");
return colors;
}

@Override
protected void onStop() {
super.onStop();
if (disposable!=null && !disposable.isDisposed()) {
disposable.dispose();
}
}
}

Create the following (fake) server implementation.

http://www.vogella.com/tutorials/RxJava/article.html 19/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.content.Context;
import android.os.SystemClock; Online Traini
(https://learn.vogel
import java.util.ArrayList;
import java.util.List;
QUICK LINKS
/** 15 OCT - RC
* This is a fake REST client.
Training
*
(http://www.vo
* It simulates making blocking calls to an REST endpoint.
*/ vogella Traini
public class RestClient { (http://www.vo
private Context mContext; vogella Books
(http://www.vo
public RestClient(Context context) {
mContext = context;
} SHARE

public List<String> getFavoriteBooks() {


SystemClock.sleep(8000);// "Simulate" the delay of
network.
return createBooks();
}

public List<String> getFavoriteBooksWithException() {


SystemClock.sleep(8000);// "Simulate" the delay of
network.
throw new RuntimeException("Failed to load");
}

private List<String> createBooks() {


List<String> books = new ArrayList<>();
books.add("Lord of the Rings");
books.add("The dark elf");
books.add("Eclipse Introduction");
books.add("History book");
books.add("Der kleine Prinz");
books.add("7 habits of highly effective people");
books.add("Other book 1");
books.add("Other book 2");
books.add("Other book 3");
books.add("Other book 4");
books.add("Other book 5");
books.add("Other book 6");
return books;
}
}

Create the activity_books.xml layout file.

http://www.vogella.com/tutorials/RxJava/article.html 20/32
7/9/2018 Using RxJava 2 - Tutorial

XML
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" Online Traini
android:layout_height="match_parent" (https://learn.vogel
>

<ProgressBar QUICK LINKS


android:id="@+id/loader" 15 OCT - RC
android:layout_width="wrap_content"
Training
android:layout_height="wrap_content"
(http://www.vo
android:layout_gravity="center"
/> vogella Traini
(http://www.vo
<android.support.v7.widget.RecyclerView vogella Books
android:id="@+id/books_list"
(http://www.vo
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" SHARE
/>

</FrameLayout>

Also implement the BooksActivity activity.

http://www.vogella.com/tutorials/RxJava/article.html 21/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; Online Traini
import android.support.v7.widget.LinearLayoutManager; (https://learn.vogel
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar; QUICK LINKS
15 OCT - RC
import java.util.List;
Training
(http://www.vo
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; vogella Traini
import io.reactivex.disposables.Disposable; (http://www.vo
import io.reactivex.schedulers.Schedulers; vogella Books
(http://www.vo

public class BooksActivity extends AppCompatActivity {


SHARE
private Disposable bookSubscription;
private RecyclerView booksRecyclerView;
private ProgressBar progressBar;
private SimpleStringAdapter stringAdapter;
private RestClient restClient;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
restClient = new RestClient(this);
configureLayout();
createObservable();
}

private void createObservable() {


Observable<List<String>> booksObservable =
Observable.fromCallable(() ->
restClient.getFavoriteBooks());
bookSubscription = booksObservable.
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribe(strings -> displayBooks(strings));
}

@Override
protected void onDestroy() {
super.onDestroy();
if (bookSubscription != null &&
!bookSubscription.isDisposed()) {
bookSubscription.dispose();
}
}

private void displayBooks(List<String> books) {


stringAdapter.setStrings(books);
progressBar.setVisibility(View.GONE);
booksRecyclerView.setVisibility(View.VISIBLE);
}

private void configureLayout() {


setContentView(R.layout.activity_books);
progressBar = (ProgressBar) findViewById(R.id.loader);
booksRecyclerView = (RecyclerView)
findViewById(R.id.books_list);
booksRecyclerView.setLayoutManager(new
LinearLayoutManager(this));
stringAdapter = new SimpleStringAdapter(this);
booksRecyclerView.setAdapter(stringAdapter);
}

http://www.vogella.com/tutorials/RxJava/article.html 22/32
7/9/2018 Using RxJava 2 - Tutorial

@Override
protected void onStop() {
super.onStop();
if (bookSubscription!=null &&
!bookSubscription.isDisposed()) { Online Traini
bookSubscription.dispose(); (https://learn.vogel
}
}
QUICK LINKS
}
15 OCT - RC
Training
8.3. Implement a long running implementation (http://www.vo

via a Callable vogella Traini


(http://www.vo
A java.util.Callable is like a runnable but it can throw an vogella Books
exception and return a value. (http://www.vo

The following activity implement a observable created based on a SHARE


Callable . During the subscription a progressbar will be make
visible and once the process finishes the progressbar is hidden
again and a text view is updated.

The long running operation will run in the background, the update
of the UI will happen in the main thread.

Here is the activity_scheduler.xml layout file:

http://www.vogella.com/tutorials/RxJava/article.html 23/32
7/9/2018 Using RxJava 2 - Tutorial

XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" Online Traini
android:layout_height="match_parent" (https://learn.vogel
>

<Button QUICK LINKS


android:id="@+id/scheduleLongRunningOperation" 15 OCT - RC
android:layout_width="wrap_content"
Training
android:layout_height="wrap_content"
(http://www.vo
android:lines="3"
android:text="Start something long" vogella Traini
android:layout_marginStart="12dp" (http://www.vo
android:layout_alignParentStart="true" vogella Books
/>
(http://www.vo

<TextView
android:id="@+id/messagearea" SHARE
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:text=""

android:layout_below="@+id/scheduleLongRunningOperation"
/>

<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"

android:layout_alignBottom="@+id/scheduleLongRunningOperation"

android:layout_toEndOf="@+id/scheduleLongRunningOperation"
/>

</RelativeLayout>

http://www.vogella.com/tutorials/RxJava/article.html 24/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import android.os.Bundle;
import android.os.SystemClock; Online Traini
import android.support.v7.app.AppCompatActivity; (https://learn.vogel
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView; QUICK LINKS
15 OCT - RC
import java.util.concurrent.Callable;
Training
(http://www.vo
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; vogella Traini
import io.reactivex.disposables.Disposable; (http://www.vo
import io.reactivex.observers.DisposableObserver; vogella Books
import io.reactivex.schedulers.Schedulers;
(http://www.vo

/** Demonstrates a long running operation of the main thread SHARE


* during which a progressbar is shown
*
*/
public class SchedulerActivity extends AppCompatActivity {

private Disposable subscription;


private ProgressBar progressBar;
private TextView messagearea;
private View button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
configureLayout();
createObservable();
}

private void createObservable() {


}

@Override
protected void onDestroy() {
super.onDestroy();
if (subscription != null && !subscription.isDisposed())
{
subscription.dispose();
}
}

private void configureLayout() {


setContentView(R.layout.activity_scheduler);
progressBar = (ProgressBar)
findViewById(R.id.progressBar);
messagearea = (TextView)
findViewById(R.id.messagearea);
button =
findViewById(R.id.scheduleLongRunningOperation);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// progressBar.setVisibility(View.VISIBLE);
Observable.fromCallable(callable).

subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainTh
read()).
doOnSubscribe(disposable ->
{

progressBar.setVisibility(View.VISIBLE);
button.setEnabled(false);

http://www.vogella.com/tutorials/RxJava/article.html 25/32
7/9/2018 Using RxJava 2 - Tutorial

messagearea.setText(messagearea.getText().toString() +"\n"
+"Progressbar set visible" );
}
). Online Traini
subscribe(getDisposableObserver()); (https://learn.vogel
}
});
QUICK LINKS
}
15 OCT - RC
Callable<String> callable = new Callable<String>() { Training
@Override (http://www.vo
public String call() throws Exception {
vogella Traini
return doSomethingLong();
} (http://www.vo
}; vogella Books
(http://www.vo
public String doSomethingLong(){
SystemClock.sleep(1000);
SHARE
return "Hello";
}

/**
* Observer
* Handles the stream of data:
*/
private DisposableObserver<String> getDisposableObserver()
{
return new DisposableObserver<String>() {

@Override
public void onComplete() {

messagearea.setText(messagearea.getText().toString() +"\n"
+"OnComplete" );
progressBar.setVisibility(View.INVISIBLE);
button.setEnabled(true);

messagearea.setText(messagearea.getText().toString() +"\n"
+"Hidding Progressbar" );
}

@Override
public void onError(Throwable e) {

messagearea.setText(messagearea.getText().toString() +"\n"
+"OnError" );
progressBar.setVisibility(View.INVISIBLE);
button.setEnabled(true);

messagearea.setText(messagearea.getText().toString() +"\n"
+"Hidding Progressbar" );
}

@Override
public void onNext(String message) {

messagearea.setText(messagearea.getText().toString() +"\n"
+"onNext " + message );
}
};
}
}

9. Testing RxJava Observables and


Subscriptions
9.1. Testing the observables
http://www.vogella.com/tutorials/RxJava/article.html 26/32
7/9/2018 Using RxJava 2 - Tutorial
g
Flowable can be tested with
io.reactivex.subscribers.TestSubscriber . Non-backpressured
Observable, Single, Maybe and Completable can be tested with
Online Traini
io.reactivex.observers.TestObserver .
(https://learn.vogel

JAVA
@Test QUICK LINKS
public void
15 OCT - RC
anObservableStreamOfEventsAndDataShouldEmitsEachItemInOrder() {
Training
Observable<String> pipelineOfData = (http://www.vo
Observable.just("Foo", "Bar"); vogella Traini
(http://www.vo
pipelineOfData.subscribe(testObserver);
vogella Books
List<Object> dataEmitted = testObserver.values(); (http://www.vo
assertThat(dataEmitted).hasSize(2);
assertThat(dataEmitted).containsOnlyOnce("Foo"); SHARE
assertThat(dataEmitted).containsOnlyOnce("Bar");
}

All base reactive types now have a test() method. This is a huge
convenience for returning TestSubscriber or TestObserver.

JAVA
TestSubscriber<Integer> ts = Flowable.range(1, 5).test();

TestObserver<Integer> to = Observable.range(1, 5).test();

TestObserver<Integer> tso = Single.just(1).test();

TestObserver<Integer> tmo = Maybe.just(1).test();

TestObserver<Integer> tco = Completable.complete().test();

10. Exercise: Writing unit tests for RxJava


10.1. Write small unit test
Create a small test to use RxJava in a test.

http://www.vogella.com/tutorials/RxJava/article.html 27/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import org.junit.Test;
Online Traini
import java.util.List; (https://learn.vogel

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter; QUICK LINKS
import io.reactivex.ObservableOnSubscribe; 15 OCT - RC
import io.reactivex.observers.TestObserver;
Training
(http://www.vo
import static junit.framework.Assert.assertTrue;
vogella Traini
(http://www.vo
public class RxJavaUnitTest { vogella Books
String result="";
(http://www.vo

// Simple subscription to a fix value


@Test SHARE
public void returnAValue(){
result = "";
Observable<String> observer = Observable.just("Hello");
// provides data
observer.subscribe(s -> result=s); // Callable as
subscriber
assertTrue(result.equals("Hello"));
}

@Test
public void expectNPE(){
Observable<Todo> todoObservable = Observable.create(new
ObservableOnSubscribe<Todo>() {
@Override
public void subscribe(ObservableEmitter<Todo>
emitter) throws Exception {
try {
List<Todo> todos =
RxJavaUnitTest.this.getTodos();
if (todos == null){
throw new NullPointerException("todos
was null");
}
for (Todo todo : todos) {
emitter.onNext(todo);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
}
});
TestObserver<Object> testObserver = new TestObserver<>
();
todoObservable.subscribeWith(testObserver);

// expect a NPE by using the TestObserver


testObserver.assertError(NullPointerException.class);
}

private List<Todo> getTodos() {


return null;
}

public class Todo {


}
}

http://www.vogella.com/tutorials/RxJava/article.html 28/32
7/9/2018 Using RxJava 2 - Tutorial

The following code demonstrates the usage of Callable together


with OkHttp and RxJava.

Online Traini
(https://learn.vogel

QUICK LINKS
15 OCT - RC
Training
(http://www.vo
vogella Traini
(http://www.vo
vogella Books
(http://www.vo

SHARE

http://www.vogella.com/tutorials/RxJava/article.html 29/32
7/9/2018 Using RxJava 2 - Tutorial

JAVA
package com.vogella.android.rxjava.simple;

import org.junit.Test;
Online Traini
import java.util.List; (https://learn.vogel

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter; QUICK LINKS
import io.reactivex.ObservableOnSubscribe; 15 OCT - RC
import io.reactivex.observers.TestObserver;
Training
(http://www.vo
import static junit.framework.Assert.assertTrue;
vogella Traini
(http://www.vo
public class RxJavaUnitTest { vogella Books
String result="";
(http://www.vo

// Simple subscription to a fix value


@Test SHARE
public void returnAValue(){
result = "";
Observable<String> observer = Observable.just("Hello");
// provides data
observer.subscribe(s -> result=s); // Callable as
subscriber
assertTrue(result.equals("Hello"));
}

@Test
public void expectNPE(){
Observable<Todo> todoObservable = Observable.create(new
ObservableOnSubscribe<Todo>() {
@Override
public void subscribe(ObservableEmitter<Todo>
emitter) throws Exception {
try {
List<Todo> todos =
RxJavaUnitTest.this.getTodos();
if (todos == null){
throw new NullPointerException("todos
was null");
}
for (Todo todo : todos) {
emitter.onNext(todo);
}
emitter.onComplete();
} catch (Exception e) {
emitter.onError(e);
}
}
});
TestObserver<Object> testObserver = new TestObserver<>
();
todoObservable.subscribeWith(testObserver);

// expect a NPE by using the TestObserver


testObserver.assertError(NullPointerException.class);
}

private List<Todo> getTodos() {


return null;
}

public class Todo {


}
}

http://www.vogella.com/tutorials/RxJava/article.html 30/32
7/9/2018 Using RxJava 2 - Tutorial

Online Traini
11. About this website
(https://learn.vogel

QUICK LINKS
Support free Questions and Tutorial & code Get the source code
content discussion license 15 OCT - RC
Training
(http://www.vo
(http://www.vogella.com/code/index.html)
(http://www.vogella.com/support.html)
(http://www.vogella.com/contact.html)
(http://www.vogella.com/license.html) vogella Traini

12. RxJava resources (http://www.vo


vogella Books
RxJava 2.0 to 1.x comparison (http://www.vo

(https://github.com/ReactiveX/RxJava/wiki/What’s-different-in-2.0)
SHARE
Rx Java with Android Examples from Kaushik Gopal
(https://github.com/kaushikgopal/RxJava-Android-Samples)

RxJava for Android


(https://medium.com/@kurtisnusbaum/rxandroid-basics-part-1-
c0d5edcf6850#.l74zr3mgh)

Dan Lew’s Grokking with RxJava series


(http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1)

Crunching RxAndroid blog series from Roberto Orgiu


(https://github.com/tiwiz/RxAndroidCrunch)

GOTO 2016 • Exploring RxJava 2 for Android • Jake Wharton


(https://www.youtube.com/watch?v=htIXKI5gOQU)

Droidcon NYC 2016 - Looking Ahead to RxJava 2


(https://www.youtube.com/watch?v=hcxMtomE6fI&t=1934s)

RxJava 2.0 Examples for Android


(https://github.com/amitshekhariitbhu/RxJava2-Android-Samples)

12.1. vogella GmbH training and consulting


support
TRAINING SERVICE & SUPPORT
(http://www.vogella.com/training (http://www.vogella.com/consulti
/) ng/)

http://www.vogella.com/tutorials/RxJava/article.html 31/32
7/9/2018 Using RxJava 2 - Tutorial

TRAINING SERVICE & SUPPORT


(http://www.vogella.com/training (http://www.vogella.com/consulti
/) ng/)
Online Traini
(https://learn.vogel
The vogella company provides The vogella company offers
comprehensive training and expert consulting QUICK LINKS
education services (http://www.vogella.com/consultin
15 OCT - RC
(http://www.vogella.com/training/) g/)
Training
from experts in the areas of services, development support (http://www.vo
Eclipse RCP, Android, Git, Java, and coaching. Our customers vogella Traini
Gradle and Spring. We offer range from Fortune 100 (http://www.vo

both public and inhouse corporations to individual vogella Books

training. Whichever course developers. (http://www.vo

you decide to take, you are SHARE


guaranteed to experience what
many before you refer to as
“The best IT class I have ever
attended”
(http://www.vogella.com/training/).

Appendix A: Copyright and License


Copyright © 2012-2018 vogella GmbH. Free use of the software
examples is granted under the terms of the Eclipse Public License
2.0 (https://www.eclipse.org/legal/epl-2.0). This tutorial is published
under the Creative Commons Attribution-NonCommercial-
ShareAlike 3.0 Germany
(http://creativecommons.org/licenses/by-nc-sa/3.0/de/deed.en) license.

See Licence (http://www.vogella.com/license.html).

Version 1.1
Last updated 2018-02-13 12:00:43 +01:00

http://www.vogella.com/tutorials/RxJava/article.html 32/32

You might also like