10. Kapusta, Stofanak - eGlu

Preview:

Citation preview

Džava reaktívne programovanieMário Kapusta & Martin Štofaňák

Dnes si povieme

1. Čo to je?

2. Prečo to je super?

3. Ako to použiť?

1. Asynchrónne prúdy dát

2. Prúd(stream) môže byť čokoľvek

3. RxJava ponúka magnifikálne možnosti

Čo to je?

Silné diagramyASYNC

SYNC

WOW

VERY SHINY

SUCH DIAGRAM

Na návrhu záleží

Už viete, čo to je a že je to super

Naprogramujeme SERVER

Observable.zip(MAGIC STUFF)- Len jedna z mnohých

- Spájanie streamov

Začneme requestom@ResponseBody @RequestMapping(method = RequestMethod.GET, value = "/dashboard") public DeferredResult<DashboardDto> getDefaultDashBoard( HttpServletRequest request, HttpServletResponse response){

final String accessToken = getAccessToken(request); final DeferredResult<DashboardDto> deffered = new DeferredResult<>(90000);

someService.dashBoard(accessToken, deffered);

return deffered;

}

User authorization(String token);

List<EmmaWatson> getAllNakedPhotos();

ChuckNorris getRandomChuckNorris();

Takto by vypadali metody normálne

Prerobíme metódy na ObservableObservable<ChuckNorris> getRandomChuckNorris(){ return Observable.create(Subscriber -> { chuck.onNext(new ChuckNorris()); chuck.onCompleted(); })

.subscribeOn(Schedulers.io()); }

Observable<User> authorization(String token);

Observable<List<EmmaWatson>> getAllNakedPhotos();

Observable<ChuckNorris> getRandomChuckNorris();

Toto bude výsledok

public Dashboard dashBoard(String token, DeferredResult<Dashboard> def){

Func2 function = (Func2<User, List<EmmaWatson>, ChuckNorris, MyDataContainer>) (user, photos, chuck) -> new Dashboard(user, photos, chuck);

Observable.zip( authorization(token), getAllNakedPhotos(), getRandomChuckNorris(), function) .subscribe(

(dashboardDto) -> def.setResult(dashboardDto), (error) -> def.setErrorResult(error)

); }

Tri streamy chceme spojiť do jedného

To bolo všetkoVďaka RX Jave bol request 2.3x rýchlejší!!!

1 166ms vs.

72ms

Android

RxAndroid- ReactiveX / RxAndroid

- minSdkVersion 10

Prečo RxAndroid ?- Api volania

- Reťazenie requestov

- Minimalizovanie “boilerplate” kódu

- Dôraz na logiku pred implemetáciou

- Modularizácia

Architektúra

Aktuálna pozícia zariadenia

Počasie pre získanú pozíciu

UI

Dáta

Architektúra

Google API client

getLocation { Location }

API GetWeatherForLocation

{ Weather }

UI

Geocoder {List<Address>}

Architektúra

Google API client

getLocation { Location }

Geocoder {List<Address>}

API GetWeatherForLocation

{ Weather }

Address provider { Address }

Weather provider{ WeatherResult }

UI

AddressProvider { Address }Observable<Address> addressObservable = Observable

.create(googleApiObservable)

.flatMap((Func1) (googleApiClient) -> { return LocationObservable.createObservable(googleApiClient);

}) .flatMap((Func1) (location) -> {

return GeocoderObservable.createObservable(context, location.getLatitude(), location.getLongitude(), ADDRESS_MAX_RESULTS);

}) .map((Func1) (addresses) -> {

return addresses.get(0); });

return addressObservable;

GoogleApiObservable { GoogleApiClient }@Override public void call(Subscriber<? super GoogleApiClient> subscriber) {

client = buildApiClient(subscriber); if(client == null)

subscriber.onError(new GoogleApiException("Error while creating api client")); try {

client.connect(); } catch (Throwable ex) {

subscriber.onError(ex); }

}

@Override public void onConnected(Bundle bundle) {

observer.onNext(client); }

LocationObservable { Location }@Override public void call(Subscriber<? super Location> subscriber) { final Location location

= LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

if(location == null) subscriber.onError(new LocationFetchFailedException());

subscriber.onNext(location); }

GeocoderObservable { List<Address> }@Override public void call(Subscriber<? super List<Address>> subscriber) {

Geocoder geocoder = new Geocoder(ctx); try { List<Address> addresses = geocoder.getFromLocation(lat, long, maxResults);

subscriber.onNext(addresses); } catch (IOException e) {

subscriber.onError(e); }

}

weatherObservable = addressProvider

.loadAddress()

.flatMap(address -> { addressString = String.format("%s,%s", address.city(), address.countryCode()); return weatherService.getTodayWeather(addressString, ”metric”);

}) .map(weatherResponse -> new WeatherResult(addressString, weatherResponse));

return weatherObservable;

WeatherProvider { WeatherResult }

public interface WeatherService { @GET("/weather") Observable<WeatherResponse> getTodayWeather(@Query("q") String location,

@Query("units") String units); }

WeatherAPI { WeatherResponse }

weatherProvider.loadWeather().subscribe(new Observer<WeatherResult>() {

@Override public void onCompleted() {}

@Override public void onError(Throwable e) { //Napr. zobrazime uzivatelovi error message

}

@Override public void onNext(WeatherResult weatherResult) { //Vyplnime UI datami o pocasi

renderView(weatherResult); }

});

UI

https://github.com/majusko/RX-Java-REST-Server https://github.com/stofo89/SimpleRxApp.git

Ďakujeme za pozornosť

Recommended