RxJava for android




Reactive
Programming
a = b + cThe learning curve
Reactive
Programming

Reactive
Programming
"Programar con flujos asincronos de datos"
Data
Stream
Iterables
for (Cat cat : cats) {
Log.i(TAG, cat.getName());
}Data
Stream
Iterables
for (Iterator<Cats> iterator = cats.iterator();
iterator.hasNext();) {
Cat cat = iterator.next();
Log.i(TAG, cat.getName());
}



Data
Stream
Observables
"La llave está en el acceso a los datos"

Observables

Request
Request
Request
Request
Request
729
86
163
84
114
StoryStoryStoryStoryStorystoryObservableObservers
729
86
163
84
114
¿Y ahora como accedo a esos datos?
storyObserver.subscribe(new Observer<Story>() {
@Override
public void onCompleted() {}
@Override
public void onNext(Story story) {
Log.i(TAG, story.getTitle());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
});Creación de observable
729
163
Observable.create(new Observable.OnSubscribe<Story>() { //1
@Override
public void call(Subscriber<? super Story> subscriber) {
if (!subscriber.isUnsubscribed()) { //2
try {
Story topStory = hackerNewsRestAdapter
.getTopStory(); //3
subscriber.onNext(topStory); //4
Story newestStory = hackerNewsRestAdapter
.getNewestStory();
subscriber.onNext(newestStory);
subscriber.onCompleted(); //5
} catch (JsonParseException e) {
subscriber.onError(e); //6
}
}
}
});
topStorynewestStorySubscriber implements Observer<Story>Schedulers
¿Y dónde quedo lo asincrono?
Observable.create(new Observable.OnSubscribe<Story>() {
//...
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());729
163
topStorynewestStory
729
163
topStorynewestStoryOperators
Convirtiendo datos
changeColor(circle,Color.RED)
Operators
Convirtiendo datos
729
86
163
84
114
StoryStoryStoryStoryStoryMap
AuthorAuthorAuthor




AuthorAuthorObservable.create(new Observable.OnSubscribe<Story>() {
//Emitting story objects...
})
.map(new Func1<Story, Author>() {
@Override
public Author call(Story story) {
return story.getAuthor();
}
})Operators
Convirtiendo datos
729
86
163
84
114
StoryStoryStoryStoryStoryflatMap
Observable.create(new Observable.OnSubscribe<Story>() {
//Emitting story objects...
})
.flatMap(new Func1<Story, Observable<Comment>>() {
@Override
public Observable<Comment> call(Story story) {
return Observable.from(story.getComments());
}
})Operators
729
86
163
84
114
StoryStoryStoryStoryStoryMap
AuthorAuthorAuthor




AuthorAuthorObservable.create(new Observable.OnSubscribe<Story>() {
//Emitting story objects...
})
.map(new Func1<Story, Author>() {
@Override
public Author call(Story story) {
return story.getAuthor();
}
})
.filter(new Func1<Author, Boolean>() {
@Override
public Boolean call(Author author) {
return author.isCage();
}
})Filter

Android
Examples
Retrolambda
Observable.just(1,2,3,4)
.first()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer);
}
});Observable.just(1,2,3,4)
.first()
.subscribe(integer -> {
System.out.print(integer);
});Observable.just(1,2,3,4)
.first()
.subscribe(System.out::print);Android
Examples
RxBinding
RxView.clicks(submitButton)
.subscribe(o -> log("submit button clicked!"));RxTextView.textChangeEvents(editText)
.subscribe(e -> log(e.text().toString()));emailChangeObservable = RxTextView.textChangeEvents(email);
passwordChangeObservable = RxTextView.textChangeEvents(password);
// force-disable the button
submitButton.setEnabled(false);
Observable.combineLatest(emailChangeObservable, passwordChangeObservable,
(emailObservable,passwordObservable) -> {
boolean emailCheck = emailObservable.text().length() >= 3;
boolean passwordCheck = passwordObservable.text().length() >= 3;
return emailCheck && passwordCheck;
}).subscribe(aBoolean -> {
submitButton.setEnabled(aBoolean);
});
Android
Examples
Retrofit
@GET(SpotifyApiConstants.ARTIST_SEARCH_URL)
Observable<ArtistSearchResponse> searchArtist(
@Query(SpotifyApiConstants.QUERY_TO_SEARCH) String query);Android
Examples
Retrofit
@GET(SpotifyApiConstants.ARTIST_SEARCH_URL)
Observable<ArtistSearchResponse> searchArtist(
@Query(SpotifyApiConstants.QUERY_TO_SEARCH) String query);myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);Android
Examples
Retrofit
@GET(SpotifyApiConstants.ARTIST_SEARCH_URL)
Observable<ArtistSearchResponse> searchArtist(
@Query(SpotifyApiConstants.QUERY_TO_SEARCH) String query);apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<ArtistSearchResponse>() {
@Override
public void call(ArtistSearchResponse artistSearchResponse) {
artistSearchResponse.getArtists();
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);Android
Examples
Retrofit
@GET(SpotifyApiConstants.ARTIST_SEARCH_URL)
Observable<ArtistSearchResponse> searchArtist(
@Query(SpotifyApiConstants.QUERY_TO_SEARCH) String query);apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
ArtistSearchResponse::getArtists,
Throwable::printStackTrace);myObservable.subscribe(onNextAction, onErrorAction, onCompleteAction);Android
Examples
Retrofit
apiService.searchArtist(query)
.observeOn(AndroidSchedulers.mainThread())
.flatMap(artistSearchResponse ->
Observable.from(artistSearchResponse.getArtists()))
.map(artist ->
apiService.getArtistBio(artist.getName()))
.subscribe(bio -> bio.getAutor());Android
Examples
Observable.just(geocoder.getFromLocation(latLng.latitude, latLng.longitude))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.filter(addresses -> !addresses.isEmpty())
.flatMap(Observable::from)
.first()
.subscribe(address -> {
callback.addressFound(address);
})That's it!
silmood
@silmood

RxJava for Android
By Petter Hdz
RxJava for Android
- 1,024