Reactive programming on Android
-
Upload
tomas-kypta -
Category
Technology
-
view
160 -
download
3
Transcript of Reactive programming on Android
![Page 1: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/1.jpg)
Reactive programming on AndroidTomáš Kypta
![Page 2: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/2.jpg)
What’s RxJava
![Page 3: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/3.jpg)
What’s RxJava
▪ combination of
– observer pattern
– iterator pattern
– functional programming
▪ composable data flow
▪ push concept
![Page 4: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/4.jpg)
Key Parts
▪ Observable
▪ Observer, Subscriber
▪ Subject
![Page 5: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/5.jpg)
Key Methods
▪ onNext(T)
▪ onCompleted()
▪ onError(Throwable)
![Page 6: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/6.jpg)
Key Methods
▪ subscribers can be replaced with Action parameters
someObservable.subscribe( onNextAction, onErrorAction, onCompleteAction);
![Page 7: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/7.jpg)
Key Methods
▪ we often ignore onError() and onComplete()
▪ risk of crashes when error occurs
someObservable.subscribe( onNextAction);
![Page 8: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/8.jpg)
What is RxJava good for?
▪ Async processing
– AsyncTask
– AsyncTaskLoader
– …
![Page 9: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/9.jpg)
What is RxJava good for?
▪ Async composition
– nested API calls
– AsyncTask callback hell
– There’s no way to do it right!
![Page 10: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/10.jpg)
What is RxJava good for?
▪ Testability
![Page 11: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/11.jpg)
Pros & Cons
▪ powerful tool
▪ conceptually difficult
– there are some tricky parts
![Page 12: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/12.jpg)
RxJava & app architecture
▪ suitable both for MVP and MVVM
![Page 13: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/13.jpg)
Example
Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { Timber.d(s); } });
![Page 14: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/14.jpg)
ExampleObservable.just("Hello, world!") .subscribe(new Subscriber<String>() { @Override public void onCompleted() {…}
@Override public void onError(Throwable e) {…}
@Override public void onNext(String s) { Timber.d(s); } });
![Page 15: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/15.jpg)
Retrolambda
▪ Enables Java 8 lambdas on Android
![Page 16: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/16.jpg)
Tip #1 - use Retrolambda
Observable.just("Hello, world!") .subscribe(s -> Timber.d(s));
Observable.just("Hello, world!") .subscribe(new Action1<String>() { @Override public void call(String s) { Timber.d(s); } });
![Page 17: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/17.jpg)
Observer vs. Subscriber
?
myObservable .subscribe(new Observer<String>() { @Override public void onCompleted() {}
@Override public void onError(Throwable e) {}
@Override public void onNext(String s) {} });
myObservable .subscribe(new Subscriber<String>() { @Override public void onCompleted() {}
@Override public void onError(Throwable e) {}
@Override public void onNext(String s) {} });
![Page 18: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/18.jpg)
Observer vs. Subscriber
▪ simpler unsubscribe() with Subscriber
myObservable .subscribe(new Subscriber<String>() { @Override public void onCompleted() { unsubscribe(); }
@Override public void onError(Throwable e) {}
@Override public void onNext(String s) {} });
![Page 19: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/19.jpg)
Operators
![Page 20: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/20.jpg)
Operators
▪ creation
▪ filtering
▪ combining
▪ transforming
▪ …
![Page 21: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/21.jpg)
Understanding operators
▪ marble diagrams
▪ RxMarbles
– rxmarbles.com
– Android app
![Page 22: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/22.jpg)
Observable Creation
▪ create()
▪ from()
▪ just()
![Page 23: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/23.jpg)
Observable Creation
▪ corner cases
▪ empty()
▪ never()
▪ error()
![Page 24: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/24.jpg)
Filtering
▪ filter()
▪ takeLast()
▪ take()
![Page 25: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/25.jpg)
Filtering
▪ first(), take(int)
▪ skip()
▪ distinct()
▪ …
![Page 26: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/26.jpg)
Combining
▪ merge()
▪ zip()
![Page 27: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/27.jpg)
Transforming
▪ map()
▪ flatMap()
▪ concatMap()
![Page 28: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/28.jpg)
map vs. flatMap vs. concatMap▪ map
– A -> B
– one in, one out
▪ flatMap
– A -> Observable<B>
– map + flatten
▪ concatMap
– ordered flatMap
![Page 29: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/29.jpg)
Aggregate
▪ concat()
▪ reduce
![Page 30: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/30.jpg)
Operators
▪ and there’s much more …
![Page 31: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/31.jpg)
Example
Observable.from(myUrls)
![Page 32: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/32.jpg)
Example
Observable.from(myUrls) .filter(url -> url.endsWith(".cz"))
![Page 33: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/33.jpg)
Example
Observable.from(myUrls) .filter(url -> url.endsWith(".cz")) .flatMap(url -> Observable.just(getHttpStatus(url)))
![Page 34: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/34.jpg)
Example
Observable.from(myUrls) .filter(url -> url.endsWith(".cz")) .flatMap(url -> Observable.just(getHttpStatus(url))) .take(5)
![Page 35: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/35.jpg)
Example
Observable.from(myUrls) .filter(url -> url.endsWith(".cz")) .flatMap(url -> Observable.just(getHttpStatus(url))) .take(5) .subscribe(s -> Timber.i(String.valueOf(s)));
![Page 36: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/36.jpg)
Threading
![Page 37: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/37.jpg)
Threading
▪ subscribeOn(Scheduler)
▪ subscribes to Observable on the Scheduler
▪ observeOn(Scheduler)
▪ Observable emits on the Scheduler
![Page 38: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/38.jpg)
Schedulers
![Page 39: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/39.jpg)
Schedulers
▪ computation()
▪ io()
▪ newThread()
▪ from(Executor)
![Page 40: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/40.jpg)
computation() vs. io()
▪ io()
– unbounded thread pool
– I/O operations
▪ computation()
– bounded thread pool
– CPU intensive computational work
![Page 41: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/41.jpg)
AndroidSchedulers
▪ mainThread()
▪ from(Looper)
![Page 42: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/42.jpg)
subscribeOn()
▪ subscribeOn()
– multiple calls useless
– only the first call works!
– for all operators
![Page 43: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/43.jpg)
observeOn()
▪ can be called multiple times
![Page 44: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/44.jpg)
Threading
▪ operators have default Schedulers
▪ check Javadoc for it
![Page 45: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/45.jpg)
Threading
▪ range()
– no preference, uses current thread
▪ interval()
– computation() thread
![Page 46: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/46.jpg)
Threading
▪ just()
– current thread
▪ delay(long, TimeUnit)
– computation() thread
![Page 47: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/47.jpg)
Observable methods
▪ extra actions
▪ doOnNext()
▪ doOnError()
▪ doOnSubscribe()
▪ doOnUnsubscribe()
▪ …
![Page 48: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/48.jpg)
Async composition
apiEndpoint.login()
![Page 49: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/49.jpg)
Async composition
apiEndpoint.login() .doOnNext(accessToken -> storeCredentials(accessToken))
![Page 50: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/50.jpg)
Async composition
apiEndpoint.login() .doOnNext(accessToken -> storeCredentials(accessToken)) .flatMap(accessToken -> serviceEndpoint.getUser())
![Page 51: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/51.jpg)
Async composition
apiEndpoint.login() .doOnNext(accessToken -> storeCredentials(accessToken)) .flatMap(accessToken -> serviceEndpoint.getUser()) .flatMap(user -> serviceEndpoint.getUserContact(user.getId()))
![Page 52: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/52.jpg)
Subscription
![Page 53: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/53.jpg)
Subscription
Subscription s = mAppInfoProvider.getAppsObservable() .subscribe( appInfo -> Timber.i(appInfo.getPackageName() );
![Page 54: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/54.jpg)
Subscription
Subscription s = mAppInfoProvider.getAppsObservable() .subscribe( appInfo -> Timber.i(appInfo.getPackageName() );
s.unsubscribe();
![Page 55: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/55.jpg)
Subscription
Subscription s = mAppInfoProvider.getAppsObservable() .subscribe( appInfo -> Timber.i(appInfo.getPackageName() );
s.unsubscribe();Timber.i("unsubscribed: " + s.isUnsubscribed());
![Page 56: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/56.jpg)
CompositeSubscription
CompositeSubscription compositeSubscription = new CompositeSubscription();
compositeSubscription.add(subscription);
![Page 57: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/57.jpg)
CompositeSubscription
CompositeSubscription compositeSubscription = new CompositeSubscription();
compositeSubscription.add(subscription);
compositeSubscription.unsubscribe();
![Page 58: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/58.jpg)
CompositeSubscription
CompositeSubscription compositeSubscription = new CompositeSubscription();
compositeSubscription.add(subscription);
compositeSubscription.unsubscribe();
compositeSubscription.clear();
![Page 59: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/59.jpg)
Bridging non-Rx APIs
![Page 60: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/60.jpg)
Bridging non-Rx APIs
▪ just()
private Object getData() {...}
public Observable<Object> getObservable() { return Observable.just(getData());}
![Page 61: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/61.jpg)
Tip #2 - defer()
▪ use defer() to avoid immediate execution
private Object getData() {...}
public Observable<Object> getObservable() { return Observable.defer( () -> Observable.just(getData()) );}
![Page 62: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/62.jpg)
Subjects
![Page 63: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/63.jpg)
Subjects
▪ Observable & Observer
▪ bridge between non-Rx API
▪ stateful
– terminal state
▪ don’t pass data after onComplete()/onError()
![Page 64: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/64.jpg)
Subjects
▪ cannot be reused
– always create a new instance when subscribing to an Observable
![Page 65: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/65.jpg)
Subjects
▪ AsyncSubject
▪ BehaviorSubject
▪ ReplaySubject
▪ PublishSubject
▪ SerializedSubject
![Page 66: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/66.jpg)
Subjects
Subject subject = …subject.subscribe(subscriber);subject.onNext(A);subject.onNext(B);
![Page 67: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/67.jpg)
AsyncSubject
▪ last item, after Observable completes
![Page 68: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/68.jpg)
BehaviorSubject
▪ emits most recent and all subsequent items
![Page 69: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/69.jpg)
PublishSubject
▪ emits only subsequent items
![Page 70: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/70.jpg)
ReplaySubject
▪ emit all the items
![Page 71: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/71.jpg)
RxRelay
![Page 72: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/72.jpg)
RxRelay
▪ https://github.com/JakeWharton/RxRelay
▪ Relay = Observable & Action1
▪ call()
▪ Relay = Subject - onComplete() - onError()
![Page 73: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/73.jpg)
RxRelay
▪ Subject
▪ stateful
▪ Relay
▪ stateless
![Page 74: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/74.jpg)
RxRelay
Relay relay = …relay.subscribe(observer);relay.call(A);relay.call(B);
![Page 75: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/75.jpg)
RxRelay
▪ BehaviorRelay
▪ PublishRelay
▪ ReplayRelay
▪ SerializedRelay
![Page 76: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/76.jpg)
Android Lifecycle
▪ problems
▪ continuing Subscription during configuration change
▪ memory leaks
![Page 77: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/77.jpg)
Android Lifecycle
▪ continuing Subscription during configuration change
▪ cache()
▪ replay()
![Page 78: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/78.jpg)
Android Lifecycle
▪ memory leaks
▪ bind to Activity/Fragment lifecycle
▪ RxLifecycle
![Page 79: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/79.jpg)
RxLifecycle
![Page 80: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/80.jpg)
RxLifecycle
▪ auto unsubscribe based on Activity/Fragment lifecyclemyObservable .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .subscribe();
myObservable .compose(RxLifecycle.bindActivity(lifecycle)) .subscribe();
![Page 81: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/81.jpg)
RxLifecycle
▪ obtain ActivityEvent or FragmentEvent by:
A. rxlifecycle-components + subclass RxActivity, RxFragment
B. Navi + rxlifecycle-navi
C. Write it yourself
![Page 82: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/82.jpg)
RxLifecycle
public class MyActivity extends RxActivity { @Override public void onResume() { super.onResume(); myObservable .compose(bindToLifecycle()) .subscribe(); }}
![Page 83: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/83.jpg)
RxLifecyclepublic class MyActivity extends NaviActivity { private final ActivityLifecycleProvider provider = NaviLifecycle.createActivityLifecycleProvider(this);
@Override public void onResume() { super.onResume(); myObservable .compose(provider.bindToLifecycle()) .subscribe(…); }}
![Page 84: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/84.jpg)
Navi
naviComponent.addListener(Event.CREATE, new Listener<Bundle>() { @Override public void call(Bundle bundle) { setContentView(R.layout.main); } });
![Page 85: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/85.jpg)
RxNavi
RxNavi.observe(naviComponent, Event.CREATE) .subscribe(bundle -> setContentView(R.layout.main));
![Page 86: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/86.jpg)
RxLifecyclepublic class MainActivityFragment extends Fragment {
BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();
![Page 87: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/87.jpg)
RxLifecyclepublic class MainActivityFragment extends Fragment {
BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();
@Override public void onResume() { super.onResume(); RxView.clicks(vBtn) .compose(RxLifecycle.bindUntilEvent(mLifecycleSubject, FragmentEvent.PAUSE)) .doOnUnsubscribe(() -> Timber.i("onUnsubscribe")) .subscribe(…); }
}
![Page 88: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/88.jpg)
RxLifecyclepublic class MainActivityFragment extends Fragment {
BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();
@Override public void onResume() { super.onResume(); RxView.clicks(vBtn) .compose(RxLifecycle.bindUntilEvent(mLifecycleSubject, FragmentEvent.PAUSE)) .doOnUnsubscribe(() -> Timber.i("onUnsubscribe")) .subscribe(…); }
@Override public void onPause() { super.onPause(); Timber.i("onPause"); mLifecycleSubject.onNext(FragmentEvent.PAUSE); }}
![Page 89: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/89.jpg)
RxBinding
![Page 90: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/90.jpg)
RxBinding
▪ binding for UI widgets
![Page 91: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/91.jpg)
RxBinding
RxView.clicks(vBtnSearch) .subscribe( v -> { Intent intent = new Intent(getActivity(), SearchActivity.class); startActivity(intent); } );
![Page 92: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/92.jpg)
RxBinding
RxTextView.textChanges(vEtSearch) .subscribe( response -> Timber.i("Count: " + response.totalCount()) );
![Page 93: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/93.jpg)
RxBinding
RxTextView.textChanges(vEtSearch) .debounce(2, TimeUnit.SECONDS) .subscribe( response -> Timber.i("Count: " + response.totalCount()) );
![Page 94: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/94.jpg)
RxBinding
RxTextView.textChanges(vEtSearch) .debounce(2, TimeUnit.SECONDS) .observeOn(Schedulers.io()) .flatMap(s -> mApiService.search(s.toString())) .subscribe( response -> Timber.i("Count: " + response.totalCount()) );
![Page 95: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/95.jpg)
RxBinding
▪ compile ‘com.jakewharton.rxbinding:rxbinding:0.4.0'
▪ compile ‘com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'
▪ compile ‘com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.4.0'
▪ compile ‘com.jakewharton.rxbinding:rxbinding-design:0.4.0'
▪ compile ‘com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.4.0'
▪ compile 'com.jakewharton.rxbinding:rxbinding-leanback-v17:0.4.0'
![Page 96: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/96.jpg)
Retrofit
![Page 97: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/97.jpg)
Retrofit
▪ sync or async API
@GET("group/{id}/users")Call<List<User>> groupList(@Path("id") int groupId);
![Page 98: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/98.jpg)
Retrofit
▪ reactive API
@GET("group/{id}/users")Observable<List<User>> groupList(@Path("id") int groupId);
![Page 99: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/99.jpg)
Retrofit
– onNext() with Response, then onComplete()
– onError() in case of error
@GET("/data")Observable<Response> getData( @Body DataRequest dataRequest);
![Page 100: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/100.jpg)
Retrofit
RxTextView.textChanges(vEtSearch) .debounce(2, TimeUnit.SECONDS) .observeOn(Schedulers.io()) .flatMap(s -> mApiService.search(s.toString())) .subscribe( response -> Timber.i("Count: " + response.totalCount()) );
![Page 101: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/101.jpg)
SQLBrite
![Page 102: Reactive programming on Android](https://reader031.fdocuments.us/reader031/viewer/2022022202/587c16fb1a28abb5068b47b3/html5/thumbnails/102.jpg)
THE END