View
14
Download
1
Category
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