@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
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 }
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