Slide 1

Slide 1 text

Subscribe { RxJava vs LiveData }

Slide 2

Slide 2 text

@brunoaybarg @bruno.aybar Bruno125 Bruno Aybar Android Lead @ Fandango Latam

Slide 3

Slide 3 text

• Trending entre Android devs • Nos permiten observar cambios sobre algún tipo de información, y operar sobre ellos • Proponen un paradigma distinto al convencional • ¿Hacen lo mismo? RxJava y LiveData

Slide 4

Slide 4 text

OBSERVER pattern

Slide 5

Slide 5 text

OBSERVER pattern Es un patrón de diseño de software que define una dependencia entre objetos (…), de manera que cuando uno de los objetos cambia su estado, notifica este cambio a todos los dependientes

Slide 6

Slide 6 text

OBSERVER RxJava LiveData pattern

Slide 7

Slide 7 text

RxJava

Slide 8

Slide 8 text

RxJava An API for asynchronous programming
 with observable streams Is a combination of the best ideas from
 the Observer pattern, the Iterator pattern, and functional programming ReactiveX RxJava RxSwift RxJS Rx.NET RxPY RxPHP …

Slide 9

Slide 9 text

Stream of Data flujo de información estados eventos data data data data

Slide 10

Slide 10 text

Fuente: Imagen tomada de https://www.pinterest.com/pin/749708669188692420/

Slide 11

Slide 11 text

Subscriber

Slide 12

Slide 12 text

Observable

Slide 13

Slide 13 text

Flowable RxJava 2:

Slide 14

Slide 14 text

package org.reactivestreams; public interface Subscriber {
 
 public void onNext(T t);
 
 public void onError(Throwable t);
 
 public void onComplete();
 }


Slide 15

Slide 15 text

Flowable.just(1)

Slide 16

Slide 16 text

Flowable.just(1) Flowable.fromArray(1,2,3)

Slide 17

Slide 17 text

Flowable.create({ s ->
 
 }, BackpressureStrategy.BUFFER) Flowable.fromArray(1,2,3) Flowable.just(1)

Slide 18

Slide 18 text

Flowable.create({ s ->
 s.onNext(1)
 
 
 
 }, BackpressureStrategy.BUFFER) Flowable.fromArray(1,2,3) Flowable.just(1)

Slide 19

Slide 19 text

Flowable.create({ s ->
 s.onNext(1)
 s.onNext(2)
 
 
 }, BackpressureStrategy.BUFFER) Flowable.just(1) Flowable.fromArray(1,2,3)

Slide 20

Slide 20 text

Flowable.create({ s ->
 s.onNext(1)
 s.onNext(2)
 s.onNext(3)
 
 }, BackpressureStrategy.BUFFER) Flowable.just(1) Flowable.fromArray(1,2,3)

Slide 21

Slide 21 text

Flowable.create({ s ->
 s.onNext(1)
 s.onNext(2)
 s.onNext(3)
 s.onComplete() 
 }, BackpressureStrategy.BUFFER) Flowable.just(1) Aquí termina el flujo Flowable.fromArray(1,2,3)

Slide 22

Slide 22 text

Flowable.create({ s ->
 s.onNext(1)
 s.onNext(2)
 s.onNext(3)
 s.onComplete() s.onNext(4)
 }, BackpressureStrategy.BUFFER) Flowable.just(1) No es emitido Flowable.fromArray(1,2,3)

Slide 23

Slide 23 text

Flowable.create({ s ->
 s.onNext(1)
 s.onNext(2)
 s.onNext(3)
 s.onError(Throwable(“Error!")) s.onNext(4)
 }, BackpressureStrategy.BUFFER) Flowable.just(1) No es emitido Flowable.fromArray(1,2,3)

Slide 24

Slide 24 text

Flowable.fromArray(1,2,3) Flowable.create({ s ->
 // heavy transaction... // async operation... }, BackpressureStrategy.BUFFER) Flowable.just(1) no es la mejor idea…

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Subscripción a los eventos

Slide 27

Slide 27 text

Flowable.just(1).subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 ) Kotlin ❤ (o Retrolambda, en su defecto)

Slide 28

Slide 28 text

Flowable.just(1).subscribe(new Consumer() {
 @Override
 public void accept(Integer integer) throws Exception {
 log("onNext: " + integer);
 }
 }, new Consumer() {
 @Override
 public void accept(Throwable throwable) throws Exception {
 log("onError" + throwable);
 }
 }, new Action() {
 @Override
 public void run() throws Exception {
 log("onComplete!");
 }
 }); Java

Slide 29

Slide 29 text

Flowable.just(1).subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 )

Slide 30

Slide 30 text

val subscription = Flowable.just(1).subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 ) subscription.dispose()

Slide 31

Slide 31 text

Manejo de hilos

Slide 32

Slide 32 text

Controller UI DataSource

Slide 33

Slide 33 text

Controller Presenter ViewModel DataSource UI

Slide 34

Slide 34 text

Controller DataSource UI

Slide 35

Slide 35 text

Controller DataSource UI Background

Slide 36

Slide 36 text

Controller DataSource UI UI Thread

Slide 37

Slide 37 text

Flowable.just(1).subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 )

Slide 38

Slide 38 text

Flowable.just(1)
 .subscribeOn(Schedulers.computation()) .subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 ) Hilo (Thread) en el que se realizará la operación

Slide 39

Slide 39 text

Flowable.just(1)
 .subscribeOn(Schedulers.computation())
 .observeOn(AndroidSchedulers.mainThread()) .subscribe(
 { value -> log("onNext: $value") },
 { error -> log("onError: $error")},
 { log("onComplete!") }
 ) Hilo (Thread) en el que se escuchará el resultado

Slide 40

Slide 40 text

Operaciones

Slide 41

Slide 41 text

Flowable.fromArray(1,2,3,4)
 .filter { it % 2 == 0 }


Slide 42

Slide 42 text

Flowable.fromArray(1,2,3,4)
 .filter { it % 2 == 0 }
 .map { it + 10 } Flowable.just(User(“1”, “Bruno”))
 .map { it.name }

Slide 43

Slide 43 text

Combine CombineLatest And/Then/When Zip Switch Join ... Filtering Filter Distinct First Last Take ... Transform Map FlatMap Scan GroupBy Buffer ... More: http:/ /reactivex.io/documentation/ operators.html

Slide 44

Slide 44 text

Curva de aprendizaje

Slide 45

Slide 45 text

LiveData

Slide 46

Slide 46 text

LiveData Room Lifecycle ViewModel ARCHITECTURE COMPONENTS

Slide 47

Slide 47 text

LiveData Lifecycle +

Slide 48

Slide 48 text

Flowable.fromArray(1,2,3)

Slide 49

Slide 49 text

Flowable.fromArray(1,2,3) 1 2 3 LiveData

Slide 50

Slide 50 text

Flowable.fromArray(1,2,3) 1 2 3 MutableLiveData data = 
 new MutableLiveData<>();
 data.setValue(1); //UI thread
 data.setValue(2); //UI thread
 data.postValue(3); //Background thread

Slide 51

Slide 51 text

Flowable.fromArray(1,2,3) 1 2 3 MutableLiveData data = 
 new MutableLiveData<>();
 data.setValue(1); //UI thread
 data.setValue(2); //UI thread
 data.postValue(3); //Background thread

Slide 52

Slide 52 text

Subscripción a los eventos

Slide 53

Slide 53 text

data.observe(lifecycleOwner, new Observer() {
 @Override
 public void onChanged(@Nullable Integer value) {
 log("onChanged: $value”)
 }
 });

Slide 54

Slide 54 text

data.observe(lifecycleOwner, Observer { value -> log("onChanged: $value”) })

Slide 55

Slide 55 text

data.observe(lifecycleOwner, Observer { value -> log("onChanged: $value”) })

Slide 56

Slide 56 text

data.observe(lifecycleOwner, Observer { value -> log("onChanged: $value”) })

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

LifecycleOwner es una clase que contiene información sobre el ciclo de vida de un componente, y permite a otros objetos observar su estado

Slide 59

Slide 59 text

LifecycleOwner es una clase que contiene información sobre el ciclo de vida de un componente, y permite a otros objetos observar su estado Destroyed Created Started Resumed Initialized

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

LifecycleObserver te permite observar el estado actual de un LifecycleOwner

Slide 62

Slide 62 text

LifecycleObserver public class MyObserver implements LifecycleObserver { 
 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
 public void connectListener() {
 
 }
 
 @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
 public void disconnectListener() {
 
 }
 }


Slide 63

Slide 63 text

Flowable
 Activity 1 2 3 se suscribe data.subscribe { value -> textView.setText("Text " + value) }

Slide 64

Slide 64 text

Flowable
 Activity se suscribe data.subscribe { value -> textView.setText("Text " + value) } destroyed 4 5 6

Slide 65

Slide 65 text

LiveData
 Activity se suscribe data.observe(lifecycleOwner, { value -> textView.setText("Text " + value) }) destroyed X

Slide 66

Slide 66 text

LiveData
 Activity se suscribe data.observe(lifecycleOwner, { value -> textView.setText("Text " + value) }) STARTED | RESUMED

Slide 67

Slide 67 text

Manejo de hilos

Slide 68

Slide 68 text

MutableLiveData data = 
 new MutableLiveData<>();
 data.setValue(1); //UI thread
 data.postValue(2); //Background thread

Slide 69

Slide 69 text

MutableLiveData data = 
 new MutableLiveData<>();
 data.setValue(1); //UI thread
 data.postValue(2); //Background thread data.observe(lifecycleOwner, { value -> // executes in UI thread })

Slide 70

Slide 70 text

Operaciones

Slide 71

Slide 71 text

val userLiveData: LiveData = … 
 val userNameLiveData = Transformations.map( userLiveData, { it.name }) Map SwitchMap Custom Transformations

Slide 72

Slide 72 text

RxJava vs LiveData Simple y sencilla Operadores poderosos Manejo de hilos Código legible Curva de aprendizaje ✔ ✔ ✔ ✘ ✔ Enfocada a Android ✔ Integración con AC ✔ Operadores no tan 
 poderosos ✘ Compatibilidad con 
 librerías ✔ Over-engineered? ✘ Conocimiento portable ✔

Slide 73

Slide 73 text

¯\_(ツ)_/¯ RxJava vs LiveData

Slide 74

Slide 74 text

Controller Presenter ViewModel Data Sources UI

Slide 75

Slide 75 text

Controller Presenter ViewModel Data Sources UI LiveData

Slide 76

Slide 76 text

Controller Presenter ViewModel Data Sources UI RxJava

Slide 77

Slide 77 text

¯\_(ツ)_/¯ RxJava vs LiveData

Slide 78

Slide 78 text

Material adicional Intro to RxJava (Christina Lee) https:/ /www.youtube.com/watch?v=XLH2v9deew0 Learning Rx (for Android) by Example https:/ /www.youtube.com/watch?v=k3D0cWyNno4 Common RxJava Mistakes https:/ /www.youtube.com/watch?v=QdmkXL7XikQ RxJava in Baby Steps https:/ /www.youtube.com/watch?v=YPf6AYDaYf8 RxMarbles http:/ /rxmarbles.com/

Slide 79

Slide 79 text

Live Data docs https:/ /developer.android.com/topic/libraries/architecture/livedata.html LiveData & Lifecycle https:/ /www.youtube.com/watch?v=jCw5ib0r9wg ViewModels, LiveData and Lifecycles, oh my! https:/ /www.youtube.com/watch?v=SlZVYkhoSq8 Android lifecycle-aware components codelab https:/ /codelabs.developers.google.com/codelabs/android-lifecycles Material adicional

Slide 80

Slide 80 text

@brunoaybarg @bruno.aybar Bruno125 Bruno Aybar Android Lead @ Fandango Latam Gracias! https://speakerdeck.com/bruno125/subscribe-rxjava-vs-livedata