Reactive Programming

with RxJava

By: Farzad Tabashir

Outline

  • Introduction
  • RxJava: Essential Concepts
  • RxJava: Advanced Concepts
  • RxJava for Android Developers

Introduction

Declarative / Imperative

Declarative / Imperative

Declarative programming


what the program must accomplish
rather than describe how to accomplish it as a sequence of the programming language primitives

Declarative / Imperative

Declarative Programming
Impretavie Programming Language (Java)
Assembly
Binary Codes
Hardware

Reactive Programming

Reactive Programming

 

wikipedia: data flows and propagation of change

simple: pushing data instead of pulling it

Reactive Programming

Reactive Extensions

 

implement reactive programming paradigm over sequence of data

Rx History

  • Rx.NET  2009

  • RxJS 2010

  • RxJava 1.x 2014 by Netflix

 

Java, Scala, C#, C++, Clojure, JavaScript, Python, Groovy, JRuby, and others

Who use ReactiveX?

RxJava

is a JVM library which

implements reactive programming 

in a declarative approach

with a functional style

What reactive-functional programming is solving?

Short answer:

  • concurrency and parallelism
  • More colloquially, it is solving callback hell
    • ​addressing reactive and asynchronous use cases in an imperative way

RxJava

  • There are different approaches to being “reactive,”
    • and RxJava is but one of them
  • RxJava is a
    • concrete implementation of reactive programming principles
    • influenced by functional and data-flow programming.
  • If your program is like most though,

    • you need to combine events (asynchronous responses from functions/network calls)

    • have conditional logic interacting between them

    • and must handle failure scenarios and resource cleanup on any and all of them

       

This is where the reactive-imperative approach begins to dramatically increase in complexity

and reactive-functional programming begins to shine

When You Need Reactive Programming

RxJava: Essentials

Observable

  • Central to RxJava is the Observable type
  •  a stream of data/events
  • It is intended for push (reactive) but can also be used for pull (interactive).
  • It is lazy rather than eager.
  • It can be used asynchronously or synchronously.
  • It can represent 0, 1, many, or infinite values or events over time.
  • “asynchronous/push ‘dual' to the synchronous/pull Iterable.”

    • By “dual,” we mean the Observable provides all the functionality of an Iterable except in the reverse flow of data: it is push instead of pull

Observable/Observer pair

interface Observable<T> {
    Subscription subscribe(Observer s)
}
interface Observer<T> {
    void onNext(T t)
    void onError(Throwable t)
    void onCompleted()
}

Iterable

for (Story story : stories) {
    Log.i(TAG, story.getTitle());
}


//This is equivalent to the following:

for (Iterator<Story> iterator = stories.iterator(); iterator.hasNext();) {
    Story story = iterator.next();
    Log.i(TAG, story.getTitle());
}

Iterable

  • Synchronous data stream
  • Pull

Observable

  • Asynchronous data stream
  • Push
Pull (Iterable) Push (Observable)
T next() onNext(T)
throws Exception onError(Throwable)
returns onCompleted()

Iterable

Observable

// Iterable<String> as Stream<String>
// that contains 75 strings
getDataFromLocalMemorySynchronously()
    .skip(10)
    .limit(5)
    .map(s -> s + "_transformed")
    .forEach(System.out::println)
// Observable<String>
// that emits 75 strings
getDataFromNetworkAsynchronously()
    .skip(10)
    .take(5)
    .map(s -> s + "_transformed")
    .subscribe(System.out::println)

Operators

  • work on observable
  • return observable
  • can be chained

Map

 transform the items emitted by an Observable by applying a function to each item

Filter

emit only those items from an Observable that pass a predicate test

Operators

Most of these operators are synchronous, meaning that they perform their computation synchronously inside the onNext() as the events pass by.

 

 

Concurrency

A single Observable stream is always serialized, but each Observable stream can operate independently of one another, and thus concurrently and/or in parallel.

Schedulers (Threading)

  • Threading in RxJava defined by Schedulers
  • Parts of a data flow can run on different threads
  • Use schedulers instead of Threads

Schedulers

  • computation()
  • io()
  • mainThread()
  • newThread()
  • from(Executor)
  • from(Looper)

Schedulers

  • operators have their default scheduler
    • check java doc

Schedulers

  • subscribeOn(Scheduler)

  • observeOn(Scheduler)

Schedulers

  • subscribeOn(Scheduler)

    • multiple calls useless

    • only the first call works

    • for all operators

Schedulers

  • observeOn(Scheduler)

    • can be called multiple times

    • changes scheduler downstream

RxJava: Advanced

Observable Types

  • 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.

Operators

Creating

Just

create an Observable that emits a particular item

From

convert various other objects and data types into Observables

Range

create an Observable that emits a particular range of sequential integers

Timer

create an Observable that emits a particular item after a given delay

Interval

create an Observable that emits a sequence of integers spaced by a given time interval

Create

create an Observable from scratch by means of a function

Defer

do not create the Observable until the observer subscribes, and create a fresh Observable for each observer

Empty/Never/Throw

no items /  not terminate / terminates with an error

Operators

Combining

Concat

emit the emissions from two or more Observables without interleaving them

Merge

combine multiple Observables into one by merging their emissions

Amb

given two or more source Observables, emit all of the items from only the first of these Observables

Zip

combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function

combineLatest

When Streams Are Not Synchronized with One Another

WithLatestFrom

All slow events appearing before the first fast event are silently dropped because there is nothing with which to combine them.

Operators

Transforming

Map

transform the items emitted by an Observable by applying a function to each item

Buffer

periodically gather items emitted by an Observable into bundles and emit these bundles rather than emitting the items one at a time

Scan

apply a function to each item emitted by an Observable, sequentially, and emit each successive value

FlatMap

transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable

GroupBy

divide an Observable into a set of Observables that each emit a different subset of items from the original Observable

Window

periodically subdivide items from an Observable into Observable windows and emit these windows rather than emitting the items one at a time

Operators

Filtering

First

emit only the first item (or the first item that meets some condition) emitted by an Observable

Last

emit only the last item (or the last item that meets some condition) emitted by an Observable

Skip

suppress the first n items emitted by an Observable

Take

emit only the first n items emitted by an Observable

Distinct

suppress duplicate items emitted by an Observable

Sample

emit the most recent items emitted by an Observable within periodic time intervals

Debounce

(throtleWithTimeout)

only emit an item from an Observable if a particular timespan has passed without it emitting another item

Operators

Error Handling

Catch

recover from an onError notification by continuing the sequence without error

A Decision Tree of Observable Operators

Side Effect Methods

  • doOnNext()
  • doOnError()
  • doOnCompleted()
  • doOnSubscribe()
  • doOnUnsubscribe()
  • ...

Async Composition

apiEndpoint.login()
    .doOnNext(accessToken ->
        storeCredentials(accessToken))
    .flatMap(accessToken ->
        serviceEndpoint.getUser())
    .flatMap( user ->
        serviceEndpoint.getUserContact(user.getId() ) )

RxJava in Android

why should i use?

Typical non-reactive app

Reactive app

RxAndroid

make writing reactive components in Android applications easy

 

 More specifically, it provides a Scheduler that schedules on the main thread or any given Looper

RxAndroid

Observable.just("one", "two", "three", "four", "five")

        .subscribeOn(Schedulers.newThread())

        .observeOn(AndroidSchedulers.mainThread())

        .subscribe(/* an Observer */);

RxBinding

RxJava binding APIs for Android UI widgets

RxBinding

RxTextView.textChanges(searchTextView)
	.filter( s -> s.length() > 2 )
	.debounce(100, TimeUnit.MILLISECONDS)
	.flatMap( s -> makeApiCall(s) )
	.subscribeOn(Schedulers.io())
	.observeOn(AndroidSchedulers.mainThread())
	.subscribe(/* attach observer */);

Retrofit

Retrofit

@POST("User/SignIn")
@FormUrlEncoded
Observable<LoginResponseModel> login(
        @Field("username") String username,
        @Field("password") String password,
);

SQLBrite & Room

Disposable and CompositeDisposable

CompositeDisposable compositeDisposable = 
                           new CompositeDisposable();
        
compositeDisposable.add(
        observable1.subscribe()
);

compositeDisposable.add(
        observable2.subscribe()
);

// onPause, onStop
compositeDisposable.dispose();

Hot vs Cold Observable

Cold Observable

run their sequence when and if they are subscribed to

Hot Observable

  • Emit values independent of individual subscriptions
  • They have their own timeline and events occur whether someone is listening or not

Publish

Cold observables become hot with the publish() operator.

Back Pressure

asynchronous feedback channel

(also sometimes referred to as async-pull or reactive-pull)


Useful operators that avoid the need for backpressure

  • throttle
  • sample
  • debounce
  • buffers and windows

Back Pressure

class MySubscriber extends Subscriber<T> {
    @Override
    public void onStart() {
      request(1);
    }

    @Override
    public void onCompleted() {
        ...
    }

    @Override
    public void onError(Throwable e) {
        ...
    }

    @Override
    public void onNext(T n) {
        ...
        request(1);
    }
}

 Real-World useful examples of using RxJava

  • Background work & concurrency 
  • Instant/Auto searching text listeners 
  • Networking with Retrofit & RxJava
  • Form validation
  • Pseudo caching
  • ...

We need

Asynchronous Programming 

We need

reactive

Asynchronous Programming

We need

parallelisable

Asynchronous Programming 

We need

composable

Asynchronous Programming

We need

readable

Asynchronous Programming

We need

RxJava !

Resourse

RxJava

By Farzad Tabashir

RxJava

  • 836