67
Kotlin и Rx в Android

"Kotlin и rx в android" Дмитрий Воронин (Avito)

Embed Size (px)

Citation preview

Page 1: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Kotlin и Rx в Android

Page 2: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Page 3: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map(new Func1<String, Integer>() {

@Override

public Integer call(String s) {

return s.hashCode();

}

})

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer i) {

System.out.println(i);

}

});

Java

Page 4: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Methodpublic interface Func1<T, R> extends Function {

R call(T t);

}

Page 5: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map(new Func1<String, Integer>() {

@Override

public Integer call(String s) {

return s.hashCode();

}

})

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer i) {

System.out.println(i);

}

});

Java

Observable.just("Hello, world!")

.map { s -> s.hashCode() }

.subscribe { i -> println(i) }

Kotlin

Page 6: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map(new Func1<String, Integer>() {

@Override

public Integer call(String s) {

return s.hashCode();

}

})

.subscribe(new Action1<Integer>() {

@Override

public void call(Integer i) {

System.out.println(i);

}

});

Java

Observable.just("Hello, world!")

.map { s -> s.hashCode() }

.subscribe { i -> println(i) }

Kotlin

Page 7: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map { s -> s.hashCode() }

.subscribe { i -> println(i) }

Page 8: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map { string -> string.hashCode() }

.subscribe { hashCode -> println(hashCode) }

Page 9: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Single Abstract Method

Observable.just("Hello, world!")

.map { it.hashCode() }

.subscribe { println(it) }

Page 10: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & High-Order functions

Page 11: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & High-Order functionsfun yourFunc(one: String, two: Func0<Int>)

Page 12: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & High-Order functionsfun yourFunc(one: String, two: () -> Int)

Page 13: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & High-Order functionsfun yourFunc(one: String, two: () -> Int)

yourFunc("Hi") { 1 }

Page 14: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & High-Order functionsObservable.combineLatest(one, two) { a, b -> a + b }

Observable.zip(one, two, three) { a, b, c -> a + b + c }

Page 15: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Data types

Page 16: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Data typesObservable.combineLatest(location, webResponse){ a, b -> Pair(a, b) }

.distinctUntilChanged()

.map { doSomething(it.first, it.second) }

Page 17: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Data typesObservable.combineLatest(location, webResponse){ a, b -> LocationAndResponse(a, b)}

.distinctUntilChanged()

.map { doSomething(it.location, it.response) }

Page 18: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Data typesdata class LocationAndResponse(val location: Location, val response: Response)

Observable.combineLatest(location, webResponse){ a, b -> LocationAndResponse(a, b)}

.distinctUntilChanged()

.map { doSomething(it.location, it.response) }

Page 19: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null safety

Page 20: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyvar a: String = "abc"

a = null // compilation error

Page 21: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyvar a: String = "abc"

a = null // compilation error

var b: String? = "abc"

b = null // ok

Page 22: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyvar a: String = "abc"

a = null // compilation error

var b: String? = "abc"

b = null // ok

val l = b.length // error: variable 'b' can be null

Page 23: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyif (b != null && b.length > 0)

print("String of length ${b.length}")

else

print("Empty string")

Page 24: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyobservable //Observable<Int?>

.filter { it != null }

.subscribe { println(it) } //Observable<Int?>

Page 25: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null SafetylistOf(1, 2, 3, null) // Array<Int?>

.filter { it != null }

.forEach { println(it) } // Array<Int?>

Page 26: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null SafetylistOf(1, 2, 3, null) // Array<Int?>

.filterNotNull()

.forEach { println(it) } // Array<Int?>

Page 27: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyfun filterNotNull() {

}

Page 28: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyfun Observable.filterNotNull() {

}

Page 29: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyfun <T> Observable<T?>.filterNotNull(): Observable<T> {

}

Page 30: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyfun <T> Observable<T?>.filterNotNull(): Observable<T> {

}

Page 31: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyfun <T> Observable<T?>.filterNotNull(): Observable<T> {

return filter { it != null } as Observable<T>

}

Page 32: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Null Safetyobservable //Observable<Int?>

.filterNotNull()

.subscribe { println(it) } //Observable<Int> PROFIT!!!

Page 33: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classes

Page 34: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classessealed class State {

class Progress() : State()

class Content(val data: Response) : State()

class Error(val error: Throwable) : State()

}

Page 35: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classesstateObservable.subscribe {

when(it) {

is State.Progress -> { /* show progress */ }

is State.Content -> { it.data /* show content */ }

is State.Error -> { it.error /* show error */ }

}

}

Page 36: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classesstateObservable

.filterByType(State.Content::class.java)

.subscribe { it.data }

Page 37: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classesstateObservable

.filterByType(State.Content::class.java)

.subscribe { it.data }

Page 38: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Sealed classesfun <T, R : T> Observable<T>.filterByType(type: Class<R>): Observable<R> =

filter { type.isInstance(it) } .map { type.cast(it) }

Page 39: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Operator overloading

Page 40: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Operator overloadingval subscription = CompositeSubscription()

subscription.add(observable1.subscribe { ... })

subscription.add(observable2.subscribe { ... })

subscription.add(observable3.subscribe { ... })

Page 41: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Operator overloadingval subscription = CompositeSubscription()

subscription.add(observable1.subscribe { ... })

subscription.add(observable2.subscribe { ... })

subscription.add(observable3.subscribe { ... })

operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription)

Page 42: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Operator overloadingval subscription = CompositeSubscription()

subscription += observable1.subscribe { ... }

subscription += observable2.subscribe { ... }

subscription += observable3.subscribe { ... }

operator fun CompositeSubscription.plusAssign(subscription: Subscription) = add(subscription)

Page 43: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Android Lifecycle

Page 44: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Lifecycle

View Model

UI events

Data events

Page 45: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBinding

Page 46: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBindingJava

RxView.clicks(button)

Page 47: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBindingJava

RxView.clicks(button)

Kotlin

button.clicks()

Page 48: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBindingJava

RxView.clicks(button)

.subscribe(RxTextView.text(textView));

Kotlin

button.clicks()

Page 49: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBindingKotlin

button.clicks()

.subscribe(textView.text())

Java

RxView.clicks(button)

.subscribe(RxTextView.text(textView));

Page 50: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxBinding

Page 51: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxLifecycle

Page 52: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxLifecycleJAVA

myObservable

.compose(RxLifecycle.bindActivity(lifecycle))

.subscribe();

Page 53: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxLifecycleKOTLIN

myObservable

.bindWithLifecycle(activity)

.subscribe {}

JAVA

myObservable

.compose(RxLifecycle.bindActivity(activity))

.subscribe();

Page 54: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

RxLifecycleKOTLIN

myObservable

.bindWithLifecycle(activity)

.subscribe {}

myObservable

.bindUntilEvent(activity,ActivityEvent.PAUSE)

.subscribe {}

JAVA

myObservable

.compose(RxLifecycle.bindActivity(activity))

.subscribe();

Page 55: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe builders

Page 56: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe builders model.dataStream()

.bindWithLifecycle(view)

.subscribe(dataHandleAction)

model.editIntent()

.bindWithLifecycle(view)

.subscribe(gotoEditAction)

model.mapData()

.bindWithLifecycle(view)

.subscribe(markersHandleAction)

Page 57: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe builders view.bindWithLifecycle {

model.dataStream() with dataHandleAction

model.editIntent() with gotoEditAction

model.mapData() with markersHandleAction

}

Page 58: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe buildersobservable.subscribe { /* on next here*/ }

Page 59: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe buildersobservable.subscribe { /* on next here*/ }

observable.subscribe ({ /* onNext */ }, { /* onError*/ })

Page 60: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe buildersobservable.subscribe { /* on next here*/ }

observable.subscribe ({ /* onNext */ }, { /* onError*/ })

observable.subscribe ({ /* onNext */ }, { /* onError*/ }, { /* onComplete*/ })

Page 61: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Rx & Type safe buildersobservable.subscribeWith {

onNext { }

onError { }

}

Page 62: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlin

Page 63: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlinval finiteObservable = Observable.from(arrayOf("1", "2", "3"))

val subscriber = TestSubscriber<String>()

finiteObservable.subscribe(subscriber)

subscriber.awaitTerminalEvent()

subscriber.assertValues("1", "2", "3")

Page 64: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlinval finiteObservable = Observable.from(arrayOf("1", "2", "3"))

fun <T> Observable<T>.assertValues(vararg values: T) {

val subscriber = TestSubscriber<T>()

this.subscribe(subscriber)

subscriber.awaitTerminalEvent()

subscriber.assertValues(*values)

}

Page 65: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlinval finiteObservable = Observable.from(arrayOf("1", "2", "3"))

fun <T> Observable<T>.assertValues(vararg values: T) {

val subscriber = TestSubscriber<T>()

this.subscribe(subscriber)

subscriber.awaitTerminalEvent()

subscriber.assertValues(*values)

}

finiteObservable.assertValues("1", "2", "3")

Page 66: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlinval finiteObservable = Observable.from(arrayOf("1", "2", "3"))

infix fun <T> Observable<T>.assertValues(values: Array<T>) {

val subscriber = TestSubscriber<T>()

this.subscribe(subscriber)

subscriber.awaitTerminalEvent()

subscriber.assertValues(*values)

}

finiteObservable assertValues arrayOf("1", "2", "3")

Page 67: "Kotlin и rx в android" Дмитрий Воронин  (Avito)

Testing Rx & Kotlinval finiteObservable = Observable.from(arrayOf("1", "2", "3"))

infix fun <T> Observable<T>.shouldProduce(values: Array<T>) {

val subscriber = TestSubscriber<T>()

this.subscribe(subscriber)

subscriber.awaitTerminalEvent()

subscriber.assertValues(*values)

}

finiteObservable shouldProduce arrayOf("1", "2", "3")