RxJava in Baby Steps

A presentation at KotlinConf in November 2017 in San Francisco, CA, USA by Annyce Davis

Slide 1

Slide 1

Slide 2

Slide 2

a learning curve

Slide 3

Slide 3

a steep learning curve

Slide 4

Slide 4

you a steep learning curve

Slide 5

Slide 5

superstar a steep learning curve you

Slide 6

Slide 6

you superstar a steep learning curve

Slide 7

Slide 7

you superstar a steep learning curve me

Slide 8

Slide 8

RxJava in baby steps @brwngrldev

Slide 9

Slide 9

asynchronous data streams

Slide 10

Slide 10

Slide 11

Slide 11

GPS Updates Time

Slide 12

Slide 12

GPS Updates Time -36.34543, 3.23445

Slide 13

Slide 13

-36.34543, 3.23445

-36.24543, 3.23425

GPS Updates Time

Slide 14

Slide 14

-36.34543, 3.23445

-36.24543, 3.23425

-35.34543, 3.13445 GPS Updates Time

Slide 15

Slide 15

Time server response

Slide 16

Slide 16

i want toys!!! Time server response

Slide 17

Slide 17

Time server response toys

Slide 18

Slide 18

Time i want toys!!! server response

Slide 19

Slide 19

Time server response

Slide 20

Slide 20

Which of the following is an asynchronous data stream? A: click events B: database access C: server response D: all of the above

Slide 21

Slide 21

A: click events B: database access C: server response D: all of the above Which of the following is an asynchronous data stream?

Slide 22

Slide 22

Slide 23

Slide 23

Slide 24

Slide 24

Slide 25

Slide 25

scientific Research

Slide 26

Slide 26

scientific Research

Slide 27

Slide 27

Slide 28

Slide 28

Slide 29

Slide 29

Data Transformation Observable.just( 5 , 6 , 7 ) .map { ";-) " . repeat ( it ) }

.subscribe { println ( it ) }

Slide 30

Slide 30

Data Transformation Observable.just(5, 6, 7) .map { ";-) " . repeat ( it ) }

.subscribe { println ( it ) } ;-) ;-) ;-) ;-) ;-)
;-) ;-) ;-) ;-) ;-) ;-)
;-) ;-) ;-) ;-) ;-) ;-) ;-)

Slide 31

Slide 31

chaining Observable.just( 5 , 6 , 7 ) .map { ";-) " . repeat ( it ) }

.filter { it . length < 24 }

.subscribe { println ( it ) }

Slide 32

Slide 32

chaining ;-) ;-) ;-) ;-) ;-)
Observable.just(5, 6, 7) .map { ";-) " . repeat ( it ) }

.filter { it . length < 24 }

.subscribe { println ( it ) }

Slide 33

Slide 33

Slide 34

Slide 34

Slide 35

Slide 35

RxJava i s. . . ? A: the silver bullet B: simply magic C: pure voodoo D: a library

Slide 36

Slide 36

RxJava i s. . . ? A: the silver bullet B: simply magic C: pure voodoo D: a library

Slide 37

Slide 37

listOf ( 5 , 6 , 7 ) . map { it * 5 }

. filter { it

25 }

kotlin collections

Slide 38

Slide 38

listOf ( 5 , 6 , 7 ) . map { it * 5 }

. filter { it

25 }

kotlin collections 5 6 7

Slide 39

Slide 39

listOf ( 5 , 6 , 7 ) . map { it * 5 }

. filter { it

25 }

kotlin collections 5 6 7 map 25 30 35

Slide 40

Slide 40

listOf ( 5 , 6 , 7 ) . map { it * 5 }

. filter { it

25 }

kotlin collections 5 6 7 map 25 30 35 filter 30 35

Slide 41

Slide 41

Slide 42

Slide 42

listOf ( 5 , 6 , 7 ) . asSequence () . map { it * 5 }

. filter { it

25 }

. toList () kotlin sequences

Slide 43

Slide 43

kotlin sequences listOf ( 5 , 6 , 7 ) . asSequence () . map { it * 5 }

. filter { it

25 }

. toList () 5 6 7

Slide 44

Slide 44

5 6 7 map filter kotlin sequences 25 listOf ( 5 , 6 , 7 ) . asSequence () . map { it * 5 }

. filter { it

25 }

. toList ()

Slide 45

Slide 45

5 6 7 map filter kotlin sequences 25 30 30 listOf ( 5 , 6 , 7 ) . asSequence () . map { it * 5 }

. filter { it

25 }

. toList ()

Slide 46

Slide 46

5 6 7 map filter kotlin sequences 25 30 35 30 35 listOf ( 5 , 6 , 7 ) . asSequence () . map { it * 5 }

. filter { it

25 }

. toList ()

Slide 47

Slide 47

Slide 48

Slide 48

asynchronous data streams

Slide 49

Slide 49

RxJava numbers

.

map { it * 5 }

. filter { it

25 }

. subscribe ()

Slide 50

Slide 50

RxJava numbers

.

map { it * 5 }

. filter { it

25 }

. subscribe () 5 25 map filter

Slide 51

Slide 51

RxJava numbers

.

map { it * 5 }

. filter { it

25 }

. subscribe () 5 6 map filter 25 30 30

Slide 52

Slide 52

RxJava numbers

.

map { it * 5 }

. filter { it

25 }

. subscribe () 5 6 map filter 25 30 30 35 7 35 35

Slide 53

Slide 53

flexible threading

Slide 54

Slide 54

schedulers

Slide 55

Slide 55

Observable.just( 5 , 6 , 7 )

.map {

";-) " . repeat ( it ) }

.subscribe {

println ( it ) }

Slide 56

Slide 56

Observable.just( 5 , 6 , 7 )

    .

subscribeOn( Schedulers.io ())

.map {

";-) " . repeat ( it ) }

.subscribe {

println ( it ) }

Slide 57

Slide 57

Slide 58

Slide 58

The Basics observable

Slide 59

Slide 59

The Basics observable observer

Slide 60

Slide 60

The Basics operators observable observer

Slide 61

Slide 61

observable

Slide 62

Slide 62

Slide 63

Slide 63

hot observable Time

Slide 64

Slide 64

hot observable Time i want hugs!!!

Slide 65

Slide 65

hot observable Time hugs

Slide 66

Slide 66

hot observable Time hugs hugs

Slide 67

Slide 67

hot observable Time hugs hugs hugs

Slide 68

Slide 68

Slide 69

Slide 69

Cold observable Time

Slide 70

Slide 70

Cold observable Time

Slide 71

Slide 71

Cold observable Time

Slide 72

Slide 72

Cold observable Time hugs

Slide 73

Slide 73

Cold observable Time hugs hugs

Slide 74

Slide 74

Cold observable Time hugs hugs hugs

Slide 75

Slide 75

Slide 76

Slide 76

where?

Slide 77

Slide 77

Observable.create<Int> { subscriber

-> }

Slide 78

Slide 78

Observable.create<Int> { subscriber

-> }

Observable.just( item1 , item2 , item3 )

Slide 79

Slide 79

Observable.create<Int> { subscriber

-> }

Observable.just( item1 , item2 , item3 ) Observable .interval( 2 , TimeUnit. SECONDS )

Slide 80

Slide 80

Observable.create<Int> { subscriber ->

}

Slide 81

Slide 81

Observable.create<Int> { subscriber ->

Logger.log( "create" ) Logger.log( "complete" ) } Logger.log( "done" )

Slide 82

Slide 82

Observable.create<Int> { subscriber ->

Logger.log( "create" ) subscriber.onNext( 5 ) subscriber.onNext( 6 ) subscriber.onNext( 7 )

Logger.log( "complete" )

} Logger.log( "done" )

Slide 83

Slide 83

Observable.create<Int> { subscriber ->

Logger.log( "create" ) subscriber.onNext(5) subscriber.onNext(6) subscriber.onNext(7) subscriber.onComplete() Logger.log( "complete" ) } Logger.log( "done" )

Slide 84

Slide 84

Slide 85

Slide 85

Slide 86

Slide 86

A: emit items B: be cold C: be hot D: all of the above Observables ca n. . .

Slide 87

Slide 87

A: emit items B: be cold C: be hot D: all of the above Observables ca n. . .

Slide 88

Slide 88

observer

Slide 89

Slide 89

interface Observer<T

{

fun onError(e: Throwable)

fun onComplete()

fun onNext(t: T )

fun onSubscribe(d: Disposable) }

Slide 90

Slide 90

interface Observer<T

{

fun onError(e: Throwable)

fun onComplete()

fun onNext(t: T )

fun onSubscribe(d: Disposable) }

Slide 91

Slide 91

interface Observer<T

{

fun onError(e: Throwable)

fun onComplete()

fun onNext(t: T )

fun onSubscribe(d: Disposable) }

Slide 92

Slide 92

interface Observer<T

{

fun onError(e: Throwable)

fun onComplete()

fun onNext(t: T )

fun onSubscribe(d: Disposable) }

Slide 93

Slide 93

interface Observer<T

{

fun onError(e: Throwable)

fun onComplete()

fun onNext(t: T )

fun onSubscribe(d: Disposable) }

Slide 94

Slide 94

observer’s lifecycle onSubscribe

Slide 95

Slide 95

observer’s lifecycle onNext Normal flow onSubscribe

Slide 96

Slide 96

observer’s lifecycle onComplete Normal flow onSubscribe onNext

Slide 97

Slide 97

observer’s lifecycle onComplete onError Normal flow onSubscribe onNext

Slide 98

Slide 98

val observer = object : Observer<Int> {

override fun onError(e: Throwable) { Logger.log(e) }

override fun onComplete() { Logger.log( "on complete" ) }

override fun onNext(t: Int) { Logger.log( "next: $ t " ) }

override fun onSubscribe(d: Disposable) { Logger.log( "on subscribe" ) } }

Slide 99

Slide 99

Slide 100

Slide 100

interface Consumer<T

{

fun accept(t: T ) }

Slide 101

Slide 101

val consumer = object : Consumer<Int> {

override fun accept(t: Int) { Logger.log( "next: $ t " ) }

}

Slide 102

Slide 102

Slide 103

Slide 103

Slide 104

Slide 104

val consumer = Consumer <Int> { t -> Logger.log( "next: $ t " ) } obs.subscribe(consumer) consumer

Slide 105

Slide 105

obs.subscribe( Consumer <Int> { t -> Logger.log( "next: $ t " ) } ) consumer

Slide 106

Slide 106

obs.subscribe( { t -> Logger.log( "next: $ t " ) } ) consumer

Slide 107

Slide 107

obs.subscribe { t -> Logger.log( "next: $ t " ) }

consumer

Slide 108

Slide 108

obs.subscribe { Logger.log( "next: $it " ) }

consumer

Slide 109

Slide 109

Slide 110

Slide 110

A: have a lifecycle

B: always complete

C: Never Error

D: all of the above Observ ers. . .

Slide 111

Slide 111

Observ ers. . . A: have a lifecycle

B: always complete

C: Never Error

D: all of the above

Slide 112

Slide 112

operator

Slide 113

Slide 113

Time Operator: map()

Slide 114

Slide 114

Time Operator: map() :-) :-(

Slide 115

Slide 115

Time Operator: map() :-) :-) :-( :-(

Slide 116

Slide 116

Time Operator: map() :-) :-) :-) :-( :-( :-(

Slide 117

Slide 117

Time Operator: map() :-) :-) :-) :-) :-( :-( :-( :-(

Slide 118

Slide 118

Operator: map() Observable.just(5, 6, 7) .map { ";-) " . repeat ( it ) }

.subscribe { println ( it ) }

Slide 119

Slide 119

Operator: map() ;-) ;-) ;-) ;-) ;-)
;-) ;-) ;-) ;-) ;-) ;-)
;-) ;-) ;-) ;-) ;-) ;-) ;-) Observable.just(5, 6, 7) .map { ";-) " . repeat ( it ) }

.subscribe { println ( it ) }

Slide 120

Slide 120

Operator: map() Observable.just(5, 6, 7) .map( object : Function<Int, String> {

override fun apply(t: Int): String {

return ";-) " . repeat (t) } })

.subscribe 

{ println ( it ) }

Slide 121

Slide 121

Operator: map() Observable.just(5, 6, 7) .map( object : Function<Int, String> {

override fun apply(t: Int): String {

return ";-) " . repeat (t) } })

.subscribe 

{ println ( it ) }

Slide 122

Slide 122

Operator: map() Observable.just(5, 6, 7) .map( object : Function<Int, String> {

override fun apply(t: Int): String {

return ";-) " . repeat (t) } })

.subscribe 

{ println ( it ) }

Slide 123

Slide 123

Operator: map() Observable.just(5, 6, 7) .map( object : Function<Int, String> {

override fun apply(t: Int): String {

return ";-) " . repeat (t) } })

.subscribe 

{ println ( it ) }

Slide 124

Slide 124

    .map(

object : Function<Int, String> {

override fun apply(t: Int): String {

return ";-) " . repeat (t) } }) .map { ";-) " . repeat ( it ) }

Slide 125

Slide 125

Slide 126

Slide 126

what’s the output? Observable.just( 1, 2, 3 ) .map { it * 2

}

.subscribe { println ( it ) }

Slide 127

Slide 127

A: 1, 2, 3

B: a, b, c

C: 2, 4, 6

D: 6, 2, 4 Observable.just( 1, 2, 3 ) .map { it * 2

}

.subscribe { println ( it ) } what’s the output?

Slide 128

Slide 128

Observable.just(1, 2, 3 ) .map { it * 2

}

.subscribe { println ( it ) } A: 1, 2, 3

B: a, b, c

C: 2, 4, 6

D: 6, 2, 4 what’s the output?

Slide 129

Slide 129

what’s the output? Observable.just( 1, 2, 3 ) .map { it * 2

}

    .filter 

{ it < 6

}

.subscribe { println ( it ) }

Slide 130

Slide 130

A: 2, 3, 1

B: 2, 4 C: 1, 2, 3

D: 6, 4 what’s the output? Observable.just( 1, 2, 3 ) .map { it * 2

}

    .filter 

{ it < 6

}

.subscribe { println ( it ) }

Slide 131

Slide 131

what’s the output? Observable.just(1, 2, 3 ) .map { it * 2

}

    .filter 

{ it < 6

}

.subscribe { println ( it ) } A: 2, 3, 1

B: 2, 4 C: 1, 2, 3

D: 6, 4

Slide 132

Slide 132

Operator: flatmap() via reactivex.io

Slide 133

Slide 133

Operator: flatmap() via reactivex.io item

Slide 134

Slide 134

Operator: flatmap() via reactivex.io item observable

Slide 135

Slide 135

Operator: flatmap() Observable.just( ,
) .flatMap( { Observable.just( ) } )

.subscribe { println ( it ) } :-( :-(

Slide 136

Slide 136

time flatmap

Slide 137

Slide 137

time flatmap :-(

Slide 138

Slide 138

time flatmap :-(

Slide 139

Slide 139

time flatmap :-(

Slide 140

Slide 140

time flatmap :-( :-(

Slide 141

Slide 141

time flatmap :-( :-(

Slide 142

Slide 142

time flatmap :-( :-(

Slide 143

Slide 143

time flatmap :-( :-(

Slide 144

Slide 144

Long Running asynchronous

Slide 145

Slide 145

Operator: flatmap() val users // Observable<User>

Slide 146

Slide 146

Operator: flatmap() val users // Observable<User>

val posts: Observable<Post>

Slide 147

Slide 147

Operator: flatmap() val users // Observable<User> val posts: Observable<Post> posts = users.flatMap { getUsersPosts( it . id ) }

Slide 148

Slide 148

Operator: flatmap() val users // Observable<User> val posts: Observable<Post> posts = users.flatMap { getUsersPosts( it . id ) }

posts.subscribe { println ( it ) }

Slide 149

Slide 149

via reactivex.io

Slide 150

Slide 150

Flowable Maybe backpressure Disposable Single completable

Slide 151

Slide 151

should you use rxjava?

Slide 152

Slide 152

like functional programing? Process items asynchronously?

compose data? handle errors gracefully? should you use rxjava?

Slide 153

Slide 153

should you use rxjava? like functional programing? Process items asynchronously?

compose data? handle errors gracefully?

Slide 154

Slide 154

it depends

Slide 155

Slide 155

The Basics operators observable observer

Slide 156

Slide 156

you

Slide 157

Slide 157

www.adavis.info @brwngrldev

Slide 158

Slide 158

• Reactive Programming on Android with RxJava ( http://amzn.to/2yOAkxn )

• Reactive Programming with RxJava ( http://amzn.to/2zQtqb5 )

• RxJava Playlist (https://goo.gl/9fw1Zv)

• Learning RxJava for Android Devs (https://goo.gl/VWxFLK )

• RxJava Video Course ( https://caster.io/courses/rxjava ) resources

Slide 159

Slide 159

slide design: @lauraemilyillustration font: Elliot 6, fontSquirrel.com