Reaktív programozás Androidon
Erdődy-Nagy Zsombor

Miről lesz szó?
- RxJava tapasztalatok Androidon, éles környezetben
- Előnyök, hátrányok, buktatók
- Alkalmazott Rx minták
Miről nem lesz szó?
- Rx alapokról kimerítően :(
Reaktív programozás
- Problémák megoldása komponálható reaktív streamekkel
- RxJava: de-facto Java-land Rx implementacio
- Hasznos linkek gyűjteménye kezdéshez: http://bit.ly/21nTbGj
Observable.range(0, Integer.MAX_VALUE)
.take(6)
.filter(it -> it % 2 == 0)
.map(it -> String.valueOf(it) + ' ')
.reduce(new StringBuilder(), (sb, it) -> sb.append(it))
.subscribeOn(Schedulers.newThread())
.observeOn(Schedulers.io())
.subscribe(System.out::println);
// Output: 0 2 4 Élő példa
Skyscanner Android App
Skyscanner Android App
- Letöltések száma > 22 millió
- ~200k sor kód
- ~30 fejlesztő
- 2 hetes release train
- Continous Integration - Condor
- Rendszeres A/B tesztelés - Dr. Jekyll
- > 1 éve használunk reaktív mintákat

Autosuggest
autosuggestInput
.throttleLast(250, TimeUnit.MILLISECONDS)
.distinctUntilChanged()
.switchMap(input -> {
return autosuggestManager.autosuggest(input);
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread)
.subscribe(results -> ...);

Korábbi keresések
Observable.zip(
// Get recent searches
recentSearchStore.getRecentSearches(),
// Get Price Alerts
priceAlertStore.getPriceAlerts(),
// Get latest saved search configuration
searchConfigStore.latestSearchConfig(),
(searches, alerts, lastConfig) -> {
// Batch the data based on common City
...
})
.flatMap(batched -> {
// Get images for the cities
return Observable.zip(
Observable.just(batched),
imageStore.getCityImage(batched.cityId()),
(ars, s) -> ars.setImageUrl(s));
});

User-vektor
userVector
// Avoid uploading too often
.throttleLast(3, TimeUnit.SECONDS)
// Upload
.flatMap(it -> userVectorStore.upload(it))
// Re-subscribe on failure
.retry()
// Upload on background thread
.subscribeOn(Schedulers.newThread())
// Don't care about the results
.subscribe();
+
- Boilerplate kód--
- Kódminőség++
- Igen aktív RxJava közösség
- Közös, de-facto minta:
- Folyamatok komponáláshoz
- Folyamatok leállításához
- Folyamatok hibáinak kezeléséhez
- Többszálúság kezeléséhez
-
- Tanulási görbe
- Debug nehézségek++
- Cargo-cult coding hatványozottan veszélyes
Buktatók
Observable.create()
- Minden ránk van bízva -> óvatosan vele
- Nincs backpressure-támogatás
- Nincs automatikus unsubscription-kezelés
- Ha lehet, inkább .just() / .from() / .defer()
Observable.defer(() -> Observable.just(expensiveCalculation()))
.subscribe(System.out::println);Leiratkozás
- Csak best-effort módon történik!
- Megtörténte után még szembejöhet 1-1 event
- Elsősorban összetettebb, többszálú streameknél
- Többnyire ritkán okoz problémát
Error blokk
- Feliratkozáskor elhagyható az Error blokk
Observable.range(0, 10)
.doOnNext(integer -> {
if (integer.equals(9)) throw new RuntimeException("Surprise!");
})
.subscribe(System.out::println); // -> felrobbanunk 9-nel :(- Könnyen lemaradhat ott is, ahol kellene
- Tipp: Teljes Subscriber használata Action-ök helyett
- Tipp: Lint check a hiányzó Error blokkokra!
Végtelen streamek
- 0...n onNext() -> onComplete() | onError()
- Megvan a helyük a végtelen streameknek is
- Pl. touch input, szenzor input
- Bizonyos operátorok viszont meglephetnek minket!
- Pl. concatMap()
Unsafe használat
- Egyes optimalizált adatszerkezetek az RxJava-n belül Unsafe alapúak
- Samsung - Android 5.0, 5.0.1, 5.0.2 -> crash :(
- Viszont kikapcsolható: If Samsung -> No Unsafe
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP &&
"samsung".equalsIgnoreCase(Build.MANUFACTURER)) {
System.setProperty("rx.unsafe-disable", "True");
}Operátorok
- Az RxJava kifejezőereje nagy, a tömörség azonban nincs ingyen
- Ne csak feltételezzünk működéseket, teszteljünk!
- Unit test, unit test, unit test
- Komplexebb streameknél hatványozottan igaz
Lambda hell
- Figyeljünk az olvashatóságra
- Komplexebb esetekben sokat segít, ha nem inline írunk mindent egy stream felépítésekor
- Főleg lambdák híján! (< Java 1.8)
- Ami segíthet:
- >= Java 1.8
- Retrolambda
- Kotlin
Köszönöm a figyelmet
Kérdések?
We're hiring!
Reaktív programozás Androidon I.
By rzsombor
Reaktív programozás Androidon I.
- 922