sviluppare app event-driven con rxjava su android

Post on 19-Jan-2017

82 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Sviluppare app event-driven con RxJava su Android

Rx

Boris D’AmatoAndroid Developer @

+BorisDAmato

@borisdamato

damatoboris

borisdamato

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Il Problema

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Il Problema

UI Thread

Main Thread

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

La Soluzione

RxJava RxJava è un’implementazione delle Reactive Extensions per la Java VM

Una libreria per realizzare programmi asincroni ed event-based utilizzando sequenze di

observable.

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Cosa significa “Reactive”?Un sistema Reattivo deve essere

ovvero

alle richieste degli utenti

a guasti ed errori

Responsivo Resiliente Elastico Orientato a messaggi

al carico di lavoro a eventi e messaggi

reagire

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Reactive Programming

Erik Meijer Ben Christensen

Rx.Net RxJava

Dávid Karnok

RxJava

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Reactive Programming

“Paradigma di programmazione basato su flussi di dati e propagazione dei cambiamenti” [Wikipedia]

Data flow Observer pattern Push vs Pull

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Gli Attori

Observable Observer Subscriber Subject

Generatore di dati

Reagisce alla ricezione dei dati

Ibrido tra Observable e

Observer

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Comunicazione Observable - Observer

Observer

subscribe

Observable

onNext()

onComplete()

onError()

onSubscribe()

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Android Time!

RecyclerView

Lista dei contatti

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Creazione di un Observableprivate Observable<String> getContacts() { return Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> e) throws Exception { List<String> contacts = new ArrayList<>();

Cursor cursor = [...];while (cursor.moveToNext()) {

String displayName = [...]; contacts.add(displayName);

}cursor.close();

for (String contact : contacts) { if (e.isDisposed()) return; e.onNext(contact); } if (!e.isDisposed()) e.onComplete();}});}

onError(Throwable e)

onNext(T item)

onComplete()

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Creazione di un Observable

List<Contact> contacts = [...];Observable.fromArray(contacts).subscribe([...]);

Observable.just()

.fromIterable().fromFuture()

.fromCallable()

.fromPublisher()

Observable.fromArray()

List<Contact> contacts = [...];Observable.just(contacts.get(0), contacts.get(1))

.subscribe([...]);

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Creazione di un Observable

Observable.empty() Observable.never() Observable.throw()

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Observer<Contact> observer = new Observer<Contact>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe");

Log.d(TAG, "isDisposed: " + d.isDisposed()); }

@Override public void onNext(Contact item) { Log.d(TAG, "onNext"); adapter.addItem(item); }

@Override public void onError(Throwable e) { Log.e(TAG, "onError: " + e.getMessage); }

@Override public void onComplete() { Log.d(TAG, "onComplete"); }};

Subscribe

List<Contact> contacts = [...];Observable.fromArray(contacts)

.subscribe(observer);

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

Giorgio Carlo Andrea Gianni

Giorgio Gianni

getContacts().filter(new Predicate<Contact>() { @Override public boolean test(Contact contact) throws Exception { return contact.getName().startsWith("G"); }})

Filter

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering (Lambda Version)

Giorgio Carlo Andrea Gianni

Giorgio Gianni

getContacts().filter(contact -> contact.getName().startsWith("G"))Filter

https://github.com/evant/gradle-retrolambda

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

Giorgio Carlo Andrea Gianni

Giorgio

getContacts().take(3)Take

Carlo Andrea

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

Giorgio Carlo Andrea Gianni

getContacts().takeLast(3)TakeLast

Carlo Andrea Gianni

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

Giorgio Carlo Giorgio Gianni

getContacts().distinct()Distinct

Carlo GianniGiorgio

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

21

getTemperature().distinct()

21 20 19 20 21 22 23 23 21 22 21

21 20 19 22 23

Distinct

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

21

getTemperature().distinctUntilChanged()

21 20 19 20 21 22 23 23 21 22 21

DistinctUntil

Changed

21 20 19 20 21 22 23 21 22 21

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

21

getTemperature().sample(30, TimeUnit.SECONDS)

21 20 19 20 21 22 23 23 21 22 21

Sampleo

ThrottleLast

20 21

30 sec 30 sec

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Filtering

21

getTemperature().throttleFirst(30, TimeUnit.SECONDS)

21 20 19 20 21 22 23 23 21 22 21

ThrottleFirst

30 sec 30 sec

21 21 22

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Transforming

Giorgio Carlo Andrea Gianni

giorgio

getContacts().map((contact) -> {contact.setName(

contact.getName().toLowerCase());return contact;

})

Map

carlo andrea gianni

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Combining

Giorgio Carlo Andrea Gianni

Giorgio

Observable.merge(getContacts(), getImportingContacts())Merge

Carlo Andrea Gianni

Marco Francesco

Marco Francesco

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Combining

21° 22° 20° 18°

21° - 17:30

Zip

17:30 18:00 18:30 19:00

16°

22° - 18:00 20° - 18:30 18° - 19:00

Observable.zip(getTemperature(), getTime(), this::updateMonitor)

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Torniamo ad Android...private Observable<Contact> getContacts() { return Observable.create(new ObservableOnSubscribe<Contact>() { @Override public void subscribe(ObservableEmitter<String> e) throws Exception { List<String> contacts = new ArrayList<>();

SharedPreferences prefs = getActivity().getPreferences(Context.MOODE_PRIVATE);Type contactType = new TypeToken<List<Contact>>(){}.getType();String contactsGson = prefs.getString(“CONTACTS”, “”);

if (!contactsGson.isEmpty())contacts = new Gson().fromJson(contactsGson, contactType);

for (Contact contact : contacts) {e.onNext(contact);

} if (!e.isDisposed()) e.onComplete();}});}

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

… e accade questo...

D/StrictMode: StrictMode policy violation; ~duration=253 ms: android.os.StrictMode$ StrictModeDiskReadViolation: policy=31violation=2 at android.os.StrictMode $AndroidBlockGuardPolicy. onReadFromDisk(StrictMode.java:1135)

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

SoluzionegetContacts()

.subscribeOn( Schedulers.io() )

.subscribe([...]);

Schedulers.

computation()

io()

immediate()

newThread()

trampoline()

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

… altro problema

android.view.ViewRoot$CalledFromWrongThreadException:

Only the original thread that created a view hierarchy can touch its views.

getContacts().subscribeOn(Schedulers.io()).observeOn( AndroidSchedulers.mainThread() ).subscribe([...]);

Soluzione

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Nella pratica

● La ricerca debba essere eseguita ogni 500 millisecondi

Vogliamo che:

● La ricerca debba partire solo dopo che sia stati inseriti almeno 3 caratteri

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

RxBinding

compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'compile 'com.jakewharton.rxbinding:rxbinding-design:0.4.0'

[ . . .]

https://github.com/JakeWharton/RxBinding

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Nella pratica

RxTextView.textChanges(searchField).debounce(500, TimeUnit.MILLISECONDS).filter( (charSequence) -> return charSequence.length() >= 3 ).subscribe( [...] )

Sviluppare App event-driven con RxJava su Android - Boris D’Amato

Grazie.

@borisdamato

+BorisDAmato

top related