reactive programming on android

88
Reactive programming on Android Tomáš Kypta

Upload: tomas-kypta

Post on 13-Jul-2015

836 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Reactive programming on Android

Reactive programming on AndroidTomáš Kypta

Page 2: Reactive programming on Android

reactive programming or functional reactive programming (FRP)

What’s reactive programming?

Page 3: Reactive programming on Android

functional– lambdas– closures– pure– composable

What’s reactive programming?

reactive– data flow– asynchronous– values– events– push

Page 4: Reactive programming on Android

• observer pattern

Reactive?

Page 5: Reactive programming on Android

Typical AppEvent Source

Views Network DB Other

Listener Listener Listener Listener

logic logiclogiclogic

State

Page 6: Reactive programming on Android

Transformation

ReactiveEvent Source

Observable Observable Observable Observable

Other

ObserverObserver

Views Network DB

Page 7: Reactive programming on Android

• abstract away from concerns about– low-level threading– side effects– synchronization– encapsulation– resource management

Reactive

Page 8: Reactive programming on Android

Java 8

Observable.toObservable(“a”, “b”, “c”) .take(2) .subscribe((arg) -> {

System.out.println(arg); });

Reactive Code

Page 9: Reactive programming on Android

• evading callback hell• How to execute heavy tasks on

background threads?• And deliver results on the main (UI)

thread?

Reactive on Android

Page 10: Reactive programming on Android

Async on Android

Page 11: Reactive programming on Android

Handler handler = new Handler();

new Thread(){

@Override

public void run() {

final String result = somethingDemanding();

handler.post(new Runnable() {

@Override

public void run() {

showResult(result);

}

});

}

}.start();

Thread + Handler

Page 12: Reactive programming on Android

Handler handler = new Handler();

new Thread(){

@Override

public void run() {

final String result = somethingDemanding();

handler.post(new Runnable() {

@Override

public void run() {

showResult(result);

}

});

}

}.start();

Thread + Handler

Page 13: Reactive programming on Android

• simple

• difficult to deliver on the main thread

• broken data flow

Thread + Handler

Page 14: Reactive programming on Android

new AsyncTask<Void, Integer, String>(){

@Override

protected String doInBackground(Void... params) {

return somethingDemanding();

}

@Override

protected void onPostExecute(String s) {

showResult(s);

}

}.execute();

AsyncTask

Page 15: Reactive programming on Android

• deals with the main thread• error-prone• difficult error propagation• difficult to bound to activity/fragment

lifecycle• difficult composition

AsyncTask

Page 16: Reactive programming on Android

class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks<String> {

@Override public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

getLoaderManager().initLoader(42, null, this);

}

@Override public Loader<String> onCreateLoader(int id, Bundle args) {

return new AsyncTaskLoader<String>(getActivity()) {

@Override public String loadInBackground() {

return doHeavyTask();

}

};

}

@Override public void onLoadFinished(Loader<String> loader, String data) {

showResult(data);

}

@Override public void onLoaderReset(Loader<String> loader) {}

}

Loaders

Page 17: Reactive programming on Android

Loaders

Page 18: Reactive programming on Android

• boilerplate • good for cursors• deals with activity/fragment lifecycle• difficult composition• difficult to adjust logic

Loaders

Page 19: Reactive programming on Android

• many other async libraries– some are better– some are worse

Async on Android

Page 20: Reactive programming on Android

RxJava

Page 21: Reactive programming on Android

• Java VM implementation of Reactive Extensions

• a library for composing flows and sequences of asynchronous data

• open-source• https://github.com/ReactiveX/RxJava

• by Netflix

RxJava

Page 22: Reactive programming on Android

• DSL for creating computation flows from async sources

• flows called Observables• push semantics of Observables

RxJava

Page 23: Reactive programming on Android

RxJava … not sure if …

Page 24: Reactive programming on Android

proxy or wrapper around an object that is not yet there

future.get() future.isDone()

• non-trivial complexity when nested• difficult to compose conditional

asynchronous execution flows

Future

Page 25: Reactive programming on Android

Iterable vs. Observable

Page 26: Reactive programming on Android

// Iterable<String>

getData()

.skip(10)

.take(5)

.map({s ->

return s + “1”})

.forEach({

println it

});

Iterable vs. Observable

// Observable<String>

getData()

.skip(10)

.take(5)

.map({s ->

return s + “1”})

.subscribe({

println it

});

Page 27: Reactive programming on Android

single items multiple items

synchronous T getData() Iterable<T> getData()

asynchronous Future<T> getData() Observable<T> getData()

Iterable vs. Observable

Page 28: Reactive programming on Android

event Iterable (pull) Observable (push)

retrieve data T next() onNext(T)

discover error throws Exception onError(Exception)

complete !hasNext() onCompleted()

Iterable vs. Observable

Page 29: Reactive programming on Android

public Observable<String> getData();

synchronous on calling thread

Observable

Calling Thread

Callback Thread

Page 30: Reactive programming on Android

public Observable<String> getData();

asynchronous on a separate thread

Observable

Calling Thread

Callback ThreadThread Pool

Page 31: Reactive programming on Android

public Observable<String> getData();

asynchronous on multiple threads

Observable

Calling Thread

Callback Threads

Thread Pool

Page 32: Reactive programming on Android

• not biased toward some particular source of asynchronicity

• the implementation chooses if the code will be blocking or non-blocking

Observable

Page 33: Reactive programming on Android

public interface Observer <T> { void onCompleted(); void onError(Throwable throwable); void onNext(T t); }

Observable

Page 34: Reactive programming on Android

public Observable<String> getStrings() {

return Observable.create(new Observable.OnSubscribe<String>() {

@Override

public void call(Subscriber<? super String> subscriber) {

try {

subscriber.onNext("Hello");

subscriber.onNext("World");

subscriber.onCompleted();

} catch (Exception ex) {

subscriber.onError(ex);

}

}

});

}

Observable

Page 35: Reactive programming on Android

Observable<String> strings = getStrings();

strings.subscribe(

new Observer<String>() {

@Override

public void onCompleted() {

Log.d("rx", "no more data");

}

@Override

public void onError(Throwable throwable) {

Log.e(“rx”, “error”, throwable);

}

@Override

public void onNext(String s) {

showResult(s);

}

});

Observer

Page 36: Reactive programming on Android

Observable<String> strings = getStrings();

strings.subscribe(

new Observer<String>() {

@Override

public void onCompleted() {

Log.d("rx", "no more data");

}

@Override

public void onError(Throwable throwable) {

Log.e(“rx”, “error”, throwable);

}

@Override

public void onNext(String s) {

showResult(s);

}

});

Observer

Page 37: Reactive programming on Android

Observable<String> strings = getStrings();

strings.subscribe(

new Observer<String>() {

@Override

public void onCompleted() {

Log.d("rx", "no more data");

}

@Override

public void onError(Throwable throwable) {

Log.e(“rx”, “error”, throwable);

}

@Override

public void onNext(String s) {

showResult(s);

}

});

Observer

Page 38: Reactive programming on Android

Observable<String> strings = getStrings();

strings.subscribe(

new Observer<String>() {

@Override

public void onCompleted() {

Log.d("rx", "no more data");

}

@Override

public void onError(Throwable throwable) {

Log.e(“rx”, “error”, throwable);

}

@Override

public void onNext(String s) {

showResult(s);

}

});

Observer

Page 39: Reactive programming on Android

Observable<String> strings = getStrings();

Subscription subsctiption = strings.subscribe(

new Observer<String>() {

@Override

public void onCompleted() {

Log.d("rx", "no more data");

}

@Override

public void onError(Throwable throwable) {

Log.e(“rx”, “error”, throwable);

}

@Override

public void onNext(String s) {

showResult(s);

}

});

Observer

Page 40: Reactive programming on Android

Subscription subsctiption;

subscription.unsubscribe();

subscription.isUnsubscribed();

Subscription

Page 41: Reactive programming on Android

Android & RxJava

Page 42: Reactive programming on Android

Android specific things for Rx• Scheduler • reliable and thread-safe with regarding

Fragment/Activity life-cycle• reactive components for Android use cases

and UI

RxAndroid

Page 43: Reactive programming on Android

• https://github.com/ReactiveX/RxAndroid• 'io.reactivex:rxandroid:0.23.0'• formerly rxjava-android

RxAndroid

Page 44: Reactive programming on Android

Observable<Bitmap> imageObservable =

Observable.create(observer -> {

return downloadBitmap();

});

imageObservable

.subscribe(image -> loadToImageView(image));

Image Loading

Page 45: Reactive programming on Android

Observable<Bitmap> imageObservable =

Observable.create(observer -> {

return downloadBitmap();

});

imageObservable

.subscribe(image -> loadToImageView(image));

Image Loading

Page 46: Reactive programming on Android

imageObservable

.subscribeOn(Schedulers.newThread())

.subscribe(image -> loadToImageView(image));

Image Loading

Page 47: Reactive programming on Android

imageObservable

.subscribeOn(Schedulers.newThread())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(image -> loadToImageView(image));

Image Loading

Page 48: Reactive programming on Android

imageObservable

.subscribeOn(Schedulers.newThread())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(image -> loadToImageView(image));

Image Loading

Page 49: Reactive programming on Android

public void onDestroy() {

super.onDestroy();

subscription.unsubscribe();

}

Lifecycle & Memory Leaks

Page 50: Reactive programming on Android

ContentObservable

.bindFragment(fragment, observable);

ContentObservable

.bindActivity(activity, observable);

Fragment/Activity Lifecycle

Page 51: Reactive programming on Android

Observable<Intent> observable = ContentObservable .fromBroadcast(context, intentFilter);

Observable<Intent> observable = ContentObservable .fromLocalBroadcast(context, intentFilter);

Broadcast Receiver

Page 52: Reactive programming on Android

Observable<OnClickEvent> observable = ViewObservable.clicks(view);

ViewObservable .bindView(view, observable);

Views

Page 53: Reactive programming on Android

Creating Observables

Page 54: Reactive programming on Android

• manually from scratch create()

Creating Observables

Page 55: Reactive programming on Android

• convert existing data structure into an Observablefrom()

– Iterable, Future, Arrayrepeat()

– emit source Observable repeatedly

Creating Observables

Page 56: Reactive programming on Android

• convert existing data structure into an Observabletimer()

– emits a single item after a given time

Creating Observables

Page 57: Reactive programming on Android

• convert existing data structure into an Observableempty()

– emits nothing and completeserror()

– emits nothing and signals an errornever()

– emits nothing at all

Creating Observables

Page 58: Reactive programming on Android

transform - map, flatMap, reduce, scanfilter - take, skip, sample, filtercombine - concat, merge, zip, cacheconcurrency - observeOn, subcribeOnerror handling - onErrorReturn

Obervables are composable

Page 59: Reactive programming on Android

Transforming Observables

Page 60: Reactive programming on Android

map()

– apply a function to each item

Transforming Observables

Page 61: Reactive programming on Android

flatMap()

– transform items into Observables and flatten

Transforming Observables

Page 62: Reactive programming on Android

scan()

– apply a function to each item sequentially and emit each successive value

Transforming Observables

Page 63: Reactive programming on Android

groupBy()

– divide into a set of Observables

Transforming Observables

Page 64: Reactive programming on Android

buffer()

– periodically gather items into bundles and emits these bundles

Transforming Observables

Page 65: Reactive programming on Android

Filtering Observables

Page 66: Reactive programming on Android

filter()

– filter emitted items

Filtering Observable

Page 67: Reactive programming on Android

take()

– emit only first n items

Filtering Observable

Page 68: Reactive programming on Android

timeout()

– emit items, but issue an exception if nothing emitted in a timespan

Filtering Observable

Page 69: Reactive programming on Android

distinct()

– suppress duplicate items

Filtering Observable

Page 70: Reactive programming on Android

takeLastBuffer() first() elementAt()

– emit only n-th elementignoreElements()

– pass only error or completed

Filtering Observable

Page 71: Reactive programming on Android

Combining Observables

Page 72: Reactive programming on Android

merge()

– combine multiple Observables

Combining Observables

Page 73: Reactive programming on Android

zip()

– combine multiple Observables via a function, emit results of the function

Combining Observables

Page 74: Reactive programming on Android

Error Handling

Page 75: Reactive programming on Android

recovering from onError() onErrorResumeNext()

– emit a sequence if error happens

Error Handling

Page 76: Reactive programming on Android

onErrorReturn()

– emit an item if error happens

Error Handling

Page 77: Reactive programming on Android

retry()

– resubscribe to a source

Error Handling

Page 78: Reactive programming on Android

Support for RxJava in other libraries

Page 79: Reactive programming on Android

@GET("/user/{id}/photo")

Observable<Photo> getUserPhoto(@Path("id") int id);

Retrofit

Page 80: Reactive programming on Android

private Object simpleMethod() { ... }

public Observable<Object> newMethod() {

return Observable.just(simpleMethod());

}

Plain old library

Page 81: Reactive programming on Android

private Object simpleMethod() { ... }

public Observable<Object> newMethod() {

return Observable.defer(() ->

Observable.just(simpleMethod())

);

}

Plain old library

Page 82: Reactive programming on Android

No lambdas on Android– use different language on Android– or rather not

Java 8 & Android

Page 83: Reactive programming on Android

transforms Java 8 compiled bytecode for older JVM

• gradle-retrolambda– https://github.com/evant/gradle-retrolambda– 'me.tatarka:gradle-retrolambda:2.4.1'

• retrolambda– https://github.com/orfjackal/retrolambda

Retrolambda

Page 84: Reactive programming on Android

strings.map(new Func1<String, Integer>() {

@Override

public Integer call(String s) {

return s.length();

}

});

Without Retrolambda

Page 85: Reactive programming on Android

strings.map(

(String s) -> { return s.length(); }

);

With Retrolambda

Page 86: Reactive programming on Android

• RxAndroid APIs not yet stabilized even though RxJava hitting version 1.0– RxAndroid version 0.23

• backpressure

Problems

Page 87: Reactive programming on Android

Questions?

Page 88: Reactive programming on Android

THE END