Share
Embed
Programacion
Una introducción con ejemplos de programación Reactiva en android
Yury Camacho
November 25, 2017
Transcript
53 slides
-
Programacion imperativa var a = 4 var b = 5
var c = a + b // el valor de ”c” es 9 var a = 10 // el valor de ”c” sigue siendo 9 -
Agenda • Programación Reactiva • Patron Observer • RxJava •
Operaciones • RxAndroid • Ejemplos -
Que es la programación reactiva? “La programación reactiva es un
paradigma de programación que está orientado a los flujos de datos(Streams) y propagación de los cambios de los datos en dicho flujo de forma asíncrona.” #DevfestCochabamba17 -
Patrón de diseño Observer “Es un patrón de diseño de
software que define una dependencia del tipo uno a muchos entre objetos, de manera que cuando uno de los objetos cambia su estado, notifica este cambio a todos los dependientes. ” Wikipedia #DevfestCochabamba17 -
RxJava • Libreria • Programación reactiva en Java/Android • Tareas
asíncronas • Concurrencia • Opreraciones sobre flujos de datos • Codigo limpio #DevfestCochabamba17 -
• java.util.observable/observer • Based GoF book Evolución RxJava • RX.NET
2009 • RxJS, Rxcpp, • RxRuby, ReactiveCocoa • RxJava 2012 Netflix • RxJava 1.0 2014 • Backpressure resuelto, • subscriber • Producer • RxJava 2.0, 2016 • Reactive Streams, • Publisher • Flowable #DevfestCochabamba17 -
3 Conceptos clave de Rx • Observable(Publisher) objetos que emiten
los datos • Observer(Subscriber) objetos que se suscriben y que son notificados cuando el observable emite datos • Schedulers Maneja la concurrencia indicando en qué thread deben ejecutarse el publisher y los subscribers #DevfestCochabamba17 -
Observable Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() { @Override public void
subscribe(ObservableEmitter<String> e) throws Exception { e.onNext("Yo"); e.onNext("No"); e.onNext("Fui"); e.onComplete(); } }); #DevfestCochabamba17 -
Observer Observer<T> observer = new Observer<T>() {; @Override public void
onNext(T s) { System.out.println("onNext(): " +s.toString()); } @Override public void onError(Throwable e) { System.out.println("onError(): " +e.getMessage()); } @Override public void onComplete() { System.out.println("Se completo e flujo" ); } }; #DevfestCochabamba17 -
Subscribe observable.subscribe(observer); onNext(): Yo onNext(): No onNext(): Fui Se completo
el flujo #DevfestCochabamba17 -
Otra O, Operators Operaciones que se realizan sobre los flujos
de datos #DevfestCochabamba17 -
Filter Observable<Integer> numObservable = Observable.just(1,2,3,4,5); numObservable.filter(integer -> integer > 2).subscribe(System.out::print);
Resultado : 3,4, 5 #DevfestCochabamba17 -
RxAndroid • Componentes rx especificos Android • Agrega Schedules especificos
Android #DevfestCochabamba17 -
Death to AsyncTasks public class MainController extends AsyncTask<String, Void,String> {
// constructor, declaración de variables, etc..... @Override protected void onPreExecute() { view.showProgress();} @Override protected String doInBackground(String... strings) { try { return connectionController.getCurrentWeather(strings[0].toString()); } catch (Exception e) { return "ERROR"; } } @Override protected void onPostExecute(String result) { view.hideProgress(); if (result.equals("ERROR")) {view.showError(); } else { Forecast forecast = Parser.getForecast(result); view.updateData(forecast); } } -
RxJava public class MainController { // constructor, decalracion de variables,
etc..... public void updateWeather(){ view.showProgress(); // mostar el progreso repository.getWeather() // Request al servidor .subscribeOn(Schedulers.io()) // Ejecusion en un nuevo hilo .observeOn(AndroidSchedulers.mainThread()) // retorno al hilo principal .subscribe( forecast -> view.updateData(forecast), throwable -> view.showError(), () -> view.hideProgress()); } } -
Ejemplos public Observable<List<Sku>> getSKUGroups(Long skuGroupId) { return api.getSKUGroups(skuGroupId) .map(skuGroupDetail ->
skuGroupDetail.getSkus()); } } #DevfestCochabamba17 -
Ejemplos Observable<List<SKUViewModel>> getListSKU(Long skuGroupId) { return repository.getSKUGroups(skuGroupId). flatMapIterable(skuList -> skuList)
.map(sku -> new SKUViewModel().copyFromSKU(sku)). toList().toObservable(); } #DevfestCochabamba17 -
View public interface WorldView { void onLoading(); void loadWorlds(List<World> worlds);
void hideLoading(); } -
public class WorldFragment extends Fragment implements WorldView { private WorldPresenter
presenter; //........ @Override public View onCreateView(.......) { presenter = new WorldPresenter(this); } @Override public void onStart() { presenter.loadWorlds(); } @Override public void onLoading() { progressBar.setVisibility(View.VISIBLE); } @Override public void loadWorlds(List<World> worlds) { adapter.updateWorlds(worlds); } @Override public void hideLoading() { progressBar.setVisibility(View.GONE); } } -
Presenter public class WorldPresenter { private WorldView mView; GetWorldListUseCase usecase;
public WorldPresenter(WorldView view) { mView = view; } public void loadWorlds() { mView.onLoading(); useCase = new GetWorldListUseCase(); useCase.execute(new WorldObserver(), null); } public class WorldObserver extends DisposableObserver<List<World>> { @Override public void onNext(List<World> value) { mView.hideLoading(); mView.loadWorlds(value); } @Override public void onError(Throwable e) { mView.hideLoading(); } @Override public void onComplete() { mView.hideLoading(); } } } -
public abstract class UseCase<T, Params> { private CompositeDisposable disposables; public
UseCase() { this.disposables = new CompositeDisposable(); } abstract Observable<T> buildUseCaseObservable(Params params); public void execute(DisposableObserver<T> observer, Params params) { final Observable<T> observable = this.buildUseCaseObservable(params) .subscribeOn(Schedulers.io()) // background thread .observeOn(AndroidSchedulers.mainThread());// observer on the AndroidSchedulers.mainThread() disposables.add(observable.subscribeWith(observer)); } } -
public class GetWorldListInteractor extends UseCase<List<World>,Void> { WorldRepositoryImpl repository; public GetWorldListInteractor()
{ repository = new WorldRepositoryImpl(); } @Override Observable<List<World>> buildUseCaseObservable(Void aVoid) { return repository.getWorlds(); } } -
public class GetWorldListInteractor extends UseCase<List<World>,Void> { WorldRepositoryImpl repository; public GetWorldListInteractor()
{ repository = new WorldRepositoryImpl(); } @Override Observable<List<World>> buildUseCaseObservable(Void aVoid) { return repository.getWorlds(); } } -
public class WorldRepositoryImpl implements WorldRepository{ @Override public Observable<List<World>> getWorlds() {
WorldApi api = RestClient.getInstance().create(WorldApi.class); return api.getWorlds().map(WorldListResponse::getWorldList ); } }