reactive programming on android
TRANSCRIPT
Reactive Programming on Android
Erik Meijer - Rx .NET Ben Christensen - Rx Java
Introduction
Getting Started
Pull X Push
Getting Started
RxAndroid Dependency
compile 'io.reactivex:rxandroid:0.24.0'
Brings all you need
RXJava and RXAndroid
Anatomy
Observable.from(doLongNetworkOp())
.subcribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver())
1. Observable
2. Observer
3. Schedulers
Anatomy
2. Observer.subscribe(getObserver())
private Observer<String> getObserver(){new Observer<String>() {
@Override public void onCompleted() { … }
@Override public void onError(Throwable e) { … }
@Override public void onNext(String string) { … } };}
Anatomy
Observable.from(doLongNetworkOp())
.subcribeOn(schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver())
1. Observable
2. Observer
3. Schedulers
Observable Observer
4. Subscription=
Subscription subscription = Observable.from(doLongNetworkOp())
.subcribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getObserver())
1. subscription.unsubscribe()
2. CompositeSubscription compSubscription;compSubscription.add(subscription);
3. compSubscription.unsubscribe()
Anatomy
Getting Started - Producer and Consumer
Stre
am
Observable ObserverEmits
item1
item2
item3
Uses item 1
Uses item 2
Uses item 3
onNext(item1)
onNext(item2)
onNext(item3)
no more items onCompleted() complete
Ops! Error… onError(error) Handles error
AsyncTask → Observable/Observer
new FindUserTask().execute(userId);
private class FindUserTask extends AsyncTask<Long, Void, Void>{ @Override protected void onPreExecute() { showLoading(); }
@Override protected User doInBackground(Long... params){ return userService.findUserById(params[0]); }
@Override protected void onPostExecute(User user){ mUserName.setText(user.getName()); hideLoading(); }}
Observable .just(userId) .flatMap(new Func1<Long, Observable<User>>(){ @Override public Observable<User> call(Long userId){ return Observable.just(userService.findUserById(userId); }).subscribeOn(Schedulers.io()) .subscribe( new Observer<User>() { @Override
public void onCompleted() { Log.d(TAG, "onCompleted"); hideLoading(); }
@Override public void onError(Throwable e) { Log.d(TAG, "onError " + e.getMessage()); }
@Override public void onNext(User user) { Log.d(TAG, "onNext"); mUserName.setText(user.getName()); } });
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Ops! Something went wrong
AsyncTask → Observable/Observer
Observable.just(userId) .flatMap(new Func1<Long, Observable<User>>(){ @Override public Observable<User> call(Long userId){ return Observable.just(service.findUserById(userId); }})
.subscribe(new Observer<User>() {
@Override public void onCompleted() { … }
@Override public void onError(Throwable e) { … }
@Override public void onNext(User user) { … } });
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
Operators
● Create● From● Just● Filter● Map● Concat● Many others...
Observable.create(new Observable.OnSubscribe<Integer>() { @Override public void call(Subscriber<? super Integer> observer) { try { if (!observer.isUnsubscribed()) { for (int i = 1; i < 5; i++) { observer.onNext(i); } observer.onCompleted(); } } catch (Exception e) { observer.onError(e); } } } );
Operators - Create
Integer[] items = { 0, 1, 2, 3, 4, 5 };
Observable myObservable = Observable.from(items);
Operators - From
Observable.just(1, 2, 3) .subscribe(new Subscriber<Integer>() { @Override public void onNext(Integer item) { System.out.println(“onNext:” + item); }
@Override public void onError(Throwable error) { System.err.println(“Error: ” + error.getMessage()); }
@Override public void omCompleted() { System.out.println("Sequence complete. ”); } });
Operators - Just
Observable.just(1, 2, 3, 4) .filter(new Func1<Integer, Boolean>(){ @Override public Boolean call(Integer number){ return (number < 4); } })
.subscribe(new Subscriber<Integer>() {
@Override public void onCompleted() { Log.d(TAG, "Sequence complete"); }
@Override public void onError(Throwable e) { Log.d(TAG, "onError"); }
@Override public void onNext(Integer number) { Log.d(TAG, "onNext " + number); } });
onNext 1
onNext 2
onNext 3
Sequence complete
Operators - Filter
Operators - Map
Operators - Concat
http://reactivex.io/documentation/operators.html
http://rxmarbles.com
A Decision Tree of Observable OperatorsI want to emit only certain items from an Observable
by filtering out those that do not match some predicate Filter
that is, only the first item First
that is, only the first items Take
that is, only the last item Last
Operators - Many Others
Questions ?