programación reactiva en android
DESCRIPTION
Ponencia ofrecida por Oier Blasco en DroidconMAD2013. Sinopsis: La programación reactiva es un paradigma de programación que se centra en los flujos de datos. La presentación trata de cómo podemos usar la programación reactiva para simplificar la programación de tareas asíncronas en android (principalmente las aplicaciones que consumen datos de servicios remotos). Para ello comenzaremos la presentación con una introducción sobre los motivos y los fundamentos de la programación reactiva y como los implementa RxJava (El port open-source hecho por Netflix de la Rx extensions de microsoft). El la segunda para parte de la presentación veremos algunos ejemplos concreto de cómo podemos aplicar estos principios a problemas cotidianos en android.TRANSCRIPT
![Page 1: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/1.jpg)
Programación Reactiva en Android
Oier Blasco Linares !@oier!Diciembre 2013
![Page 2: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/2.jpg)
Contenido
• Limitaciones de los componentes android.!• Introducción a RxJava.!• Concurrencia.!• Pros y Contras.!• Preguntas.
![Page 3: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/3.jpg)
Limitaciones de los componentes Android
![Page 4: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/4.jpg)
Intent Service
• No especifica como notificar a los clientes.!• Ningún controlo sobre la concurrencia.!• No especifican método de gestión de errores.
![Page 5: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/5.jpg)
AsyncTask
• Implementación cambia dependiendo del la version de android.!• En la version actual se ejecutan en serie.!• Suelen ser fuente de context leak.!• No especifican método de gestión de errores/excepciones.
![Page 6: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/6.jpg)
Programación reactiva
![Page 7: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/7.jpg)
Programación reativa Definición
“La programación reactiva es un paradigma de programación orientado a flujos de datos y a la
propagación de cambios. “ Wikipedia
![Page 8: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/8.jpg)
Programación imperativa ejemplo
X = 10;!
y = x + 5;!
X= 20!
Cual es el valor de Y? 15
![Page 9: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/9.jpg)
Programación reactiva ejemplo
X = 10;!
Func<int> y = () -> {x + 5};!
X= 20!
Cual es el valor de Y? 25
![Page 10: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/10.jpg)
RX JAVA
![Page 11: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/11.jpg)
RxJava
• Una librería para componer programas asíncronos y basados en evento mediante el uso de secuencias observables.!
• Open source.!• Creada por Netflix.!• Un port de “Reactive extension” creadas por Microsoft.!• Observable / Observer como elementos basicos.
![Page 12: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/12.jpg)
Observable
• Una secuencia de valores , finita o infinita.!• Permite la subscripción de observer mediante el método
subscribe.!• Lazy evaluation.!
![Page 13: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/13.jpg)
Observer
• Extension del patron observer de GoF.!• Se subscribe a objectos que implemente el interfaz
Observable y reacciona a lo items que este emita.!• El observer “espera” de manera no bloquean los valores
emitidos por el Observable.!
!
![Page 14: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/14.jpg)
ObserverObserver<String> stringObserver = new Observer<String> {!
public void onNext(String value) { System.out.println(“ NextValue : ” + value); } public void onCompleted() { System.out.println(“Done!”); } public void onError(Throwable t) { System.out.println(“ERROR!!!!!”); } }
![Page 15: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/15.jpg)
Observable
Observable.create( new Observable.OnSubscribeFunc<String>() {! public Subscription onSubscribe(Observer<? super String> observer) { observer.onNext("[email protected]"); observer.onNext("[email protected]"); observer.onNext("[email protected]"); observer.onNext("[email protected]");! observer.onCompleted();! return Subscriptions.empty(); }!});
![Page 16: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/16.jpg)
Composición
![Page 17: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/17.jpg)
Composición• Los Observables pueden modificados mediante operadores.!• Estos operadores permiten filtrar , combinar y transformar las
secuencias representadas por los Observables.!• Los operadores retornan otros observables con lo cual se pueden
concatenar para producir la secuencia de datos deseada.!• RxJava viene con más de 50 operadores.!• Es posible crear mas operadores para ajustarlos a nuestras necesidades.!• Los “Marble diagrams” se usan en la documentación de RxJava para
explicar el funcionamiento de los operadores de una forma gráfica. !
![Page 18: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/18.jpg)
private static Observer<Integer> createIntegerObserver(){ return new Observer<Integer>() {! public void onCompleted() { System.out.println("Sequence complete"); }! public void onError(Throwable throwable) { String msg = throwable.getMessage(); System.out.println("Error: “+ msg); }! public void onNext(Integer i) { System.out.println(i) } };}
Observer de ejemplo
![Page 19: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/19.jpg)
Map
Integer[] values = new Integer[]{1, 2, 3, 4, 5};Observable<Integer> numbers = Observable.from(values);!numbers.map(new Func1<Integer, Integer>() { public Integer call(Integer i) { return i * i; } }).subscribe(observer);
Output:
1!4!9!16!25!
Transforma la secuencia mediante la función
![Page 20: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/20.jpg)
MapMany
Observable<String> myStockSymbols = StocksService.myPortfolio();Observer<StockInfo> stockInfoObserver = createStockInfoObserver();!myStockSymbols.mapMany(new Func1<String, Observable<StockInfo>>() { public Observable<StockInfo> call(String stockSymbol) { return StocksService.getLastQuotes(stockSymbol); }!}).subscribe(stockInfoObserver);
[AAPL -> 25,730120]![GOOG -> 23,464752]![GOOG -> 11,255009]!Sequence complete
Output:
Combina n secuencias mediante la función
![Page 21: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/21.jpg)
Reduce
Integer[] values = new Integer[]{1, 2, 3, 4, 5};Observable<Integer> numbers = Observable.from(values);Observer<Integer> observer = createIntegerObserver();!numbers.reduce(new Func2<Integer, Integer, Integer>() { public Integer call(Integer a , Integer b) { return a + b; } }).subscribe(observer);
15!Sequence complete
Output:
Aplica una función a cada item devolviendo únicamente el acumulado
![Page 22: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/22.jpg)
Filter
Integer[] values = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9};Observable<Integer> numbers = Observable.from(values);Observer<Integer> observer = createIntegerObserver();!numbers.filter(new Func1<Integer, Boolean>() { public Boolean call(Integer i) { return (i % 2 == 0); } }).subscribe(observer);
2!4!6!8!Sequence complete
Output:
Filtra la secuencia en base a la función suministrada
![Page 23: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/23.jpg)
SkipWhile
Integer[] values = new Integer[]{1, 2, 3, 4, 5, 4, 3, 2, 1}; Observable<Integer> numbers = Observable.from(values);!Observer<Integer> observer = createIntegerObserver(); numbers.skipWhile(new Func1<Integer, Boolean>() { public Boolean call(Integer i) { return (i <4); }}).subscribe(observer);
4!5!4!3!2!1!Sequence complete
Output:
No emite los valores hasta que una condición se cumple
![Page 24: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/24.jpg)
Take
Integer[] values = new Integer[]{1, 2, 3, 4, 5, 4, 3, 2, 1}; Observable<Integer> numbers = Observable.from(values);!Observer<Integer> observer = createIntegerObserver();numbers.take(2).subscribe(observer);
1!2!Sequence complete
Output:
Emite solo los N elementos de la lista
![Page 25: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/25.jpg)
Distinct
Integer[] values = new Integer[]{1, 2, 1, 2, 3, 3, 4, 1, 2};Observable<Integer> numbers = Observable.from(values);Observer<Integer> observer =createIntegerObserver();!numbers.distinct().subscribe(observer);
1!2!3!4!Sequence complete
Output:
Elimina los duplicados de la secuencia
![Page 26: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/26.jpg)
Merge
Observable<Integer> odds = Observable.from(new Integer[]{1, 3, 5, 7}); Observable<Integer> evens = Observable.from(new Integer[]{2,4,6}); Observer<Integer> observer = createIntegerObserver();Observable.merge(odds,evens).subscribe(observer);
1!3!2!5!4!7!6!Sequence complete
Output:
Fusiona n secuencias
![Page 27: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/27.jpg)
Zip
Observable<Integer> odds = Observable.from(new Integer[]{1, 3, 5, 7}); Observable<Integer> evens = Observable.from(new Integer[]{2,4,6}); Observer<String> observer = createStringObserver(); Observable.zip(odds,evens ,new Func2<Integer, Integer, String>() { public String call(Integer a, Integer b) { return String.format("[%s,%s]",a,b); }! }).subscribe(observer);
[1, 2]![3, 4]![5, 6]!Sequence complete
Output:
Combina n secuencias mediante la función
![Page 28: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/28.jpg)
Concurrencia
![Page 29: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/29.jpg)
Schedulers• Los observables son mono hilo (single threaded) por defecto.!• Los scheduler se usan para introducir la concurrencia permitiendo ejecutar
partes de nuestro cadena de observables concurrentemente.!• Hay dos aspectos de nuestros Observables de los que queremos poder
controlar la concurrencia:!• En la invocación de la subscripción. Para ello usaremos el método
Observable.observeOn(Scheduler s).!• En las notificaciones al Observer. Para ello usaremos el método
Observable.notifyOn(Scheduler s).!• Hay varia implementaciones de los schedulers. Ex:
CurrentThreadScheduler, ExecutorScheduler, NewThreadScheduler, …
![Page 30: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/30.jpg)
Schedulers - Ejemplopublic class WeatherAPI!
public static Observable<WeatherData> getWeatherFromCities(String ... cities){ return Observable.from(cities).map(new Func1<String,WeatherData>() { public WeatherData call(String s) { // Call to remote api return RemoteService.getWeatherData(s); } }).subscribeOn(Schedulers.threadPoolForIO()); }}
![Page 31: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/31.jpg)
Schedulers - EjemploString [] cities= { "Madrid","Barcelona","Bilbao"} ;
WeatherAPI.getWeatherFromCities(cities)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<WeatherData>() {
// Safe to call UI code from here
public void onCompleted() { … }
public void onError(Throwable throwable) { … }
public void onNext(String s) { … }
}});
![Page 32: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/32.jpg)
Pros
• Método simple y uniforme de tratar los eventos y los errores (onNext, onError,onCompleted).!
• Podemos crea APIS que mantengan el control sobre la concurrencia .!
• Facilmente Testeable.!• Reusable permite que el cliente extienda/adapte la
secuencia usando los operadores.!
![Page 33: Programación Reactiva en Android](https://reader038.vdocuments.site/reader038/viewer/2022102618/557b9f1ed8b42a631d8b4e7f/html5/thumbnails/33.jpg)
Contras
• Curva de aprendizaje.!• Sintaxis de java 6 ( Java 8 lo mejora pero no esta
disponible para programación en android).