Slide 1

Slide 1 text

`Rxify` Presented By : Garima Jain @ragdroid A Talk to Remember

Slide 2

Slide 2 text

`Rxify` Presented By : Garima Jain @ragdroid A Talk to Remember A Walk to Remember

Slide 3

Slide 3 text

`Rxify` Presented By : Garima Jain @ragdroid A Talk to Remember A Walk to Remember A Walk-through Remember

Slide 4

Slide 4 text

`Rxify` Presented By : Garima Jain @ragdroid A Talk to Remember A Walk to Remember A Walk-through Remember - CODELAB -

Slide 5

Slide 5 text

Who?

Slide 6

Slide 6 text

`Rxify` is for? • Already working on RxJava - More to learn.

Slide 7

Slide 7 text

`Rxify` is for? • Already working on RxJava - More to learn. • Beginner - Time to start Rxifying your apps

Slide 8

Slide 8 text

`Rxify` is for? • Already working on RxJava - More to learn. • Beginner - Time to start Rxifying your apps • Pros - Sit and relax!

Slide 9

Slide 9 text

What?

Slide 10

Slide 10 text

• `Rxify` - term signifies use of RxJava • RxJava makes our lives simpler. • Cast a spell (use an operator) and we are good to go. `Rxify`

Slide 11

Slide 11 text

• Reactive Extensions for JVM (Java Virtual Machine). • Observer pattern for sequences of data / events. RxJava

Slide 12

Slide 12 text

RxJava makes lives simpler • Never having to worry about : • Low-level Threading • Synchronisation • Background Processing

Slide 13

Slide 13 text

Why?

Slide 14

Slide 14 text

RxJava operators at first glance

Slide 15

Slide 15 text

RxJava operators at first glance

Slide 16

Slide 16 text

RxJava operators at first glance • Complex • Hard to understand • Marble Diagrams? What!!

Slide 17

Slide 17 text

`Rxify` your apps!

Slide 18

Slide 18 text

Basics

Slide 19

Slide 19 text

• Observable produces items, • Subscriber consumes those items. • Observable calls : (Actions) • onNext() multiple times • followed by onComplete() • OR onError() Basics

Slide 20

Slide 20 text

• Operators : • manipulate items between producer and consumer. • Schedulers • Main Thread • Computation (Background Thread) • Test Scheduler Basics

Slide 21

Slide 21 text

Observable Pattern Producer Consumer A B C items Observable emits Subscriber consumes

Slide 22

Slide 22 text

“Part 1” Spells

Slide 23

Slide 23 text

Just-ify “create an Observable that emits a particular item”

Slide 24

Slide 24 text

Just-ify

Slide 25

Slide 25 text

Check it Out! via-Hedwig Checkout commit : “Starting commit of Codelab" git checkout

Slide 26

Slide 26 text

Observable.just("Hello World!”); Just-ify

Slide 27

Slide 27 text

Empty “create an Observable that emits no items but terminates normally”

Slide 28

Slide 28 text

Empty

Slide 29

Slide 29 text

Empty Observable.empty()

Slide 30

Slide 30 text

Never “create an Observable that emits no items and does not terminate”

Slide 31

Slide 31 text

Never

Slide 32

Slide 32 text

Never Observable.never()

Slide 33

Slide 33 text

Throw “create an Observable that emits no items and terminates with an error”

Slide 34

Slide 34 text

Throw

Slide 35

Slide 35 text

Throw Observable.error(new RuntimeException(“BOOM!"))

Slide 36

Slide 36 text

Range “create an Observable that emits a particular range of sequential integers”

Slide 37

Slide 37 text

Range

Slide 38

Slide 38 text

Range Observable.range(1, 10)

Slide 39

Slide 39 text

Interval “create an Observable that emits a sequence of integers spaced by a given time interval”

Slide 40

Slide 40 text

Interval

Slide 41

Slide 41 text

Interval Observable.interval(1000, TimeUnit.MILLISECONDS)

Slide 42

Slide 42 text

IntervalRange Observable.intervalRange(20, 5, 1000, 1000, TimeUnit.MILLISECONDS)

Slide 43

Slide 43 text

From “convert various other objects and data types into Observables”

Slide 44

Slide 44 text

From

Slide 45

Slide 45 text

From Observable.fromIterable( Arrays.asList(1, 2, 3, 4, 5, 6))

Slide 46

Slide 46 text

“Part 2” TO-DOs

Slide 47

Slide 47 text

“emit only those items from an Observable that pass a predicate test” Filter-rum

Slide 48

Slide 48 text

Filter-rum Filter-rum Observable Observable 1 2 3 1 4 5 6 3 5 7 7

Slide 49

Slide 49 text

Check it Out! via-Hedwig Checkout commit : “starting part 2" git checkout

Slide 50

Slide 50 text

Filter-rum Input : Observable.range(0,10); //TODO Print all even numbers

Slide 51

Slide 51 text

Filter-rum Observable.range(0,10)
 .filter(new Predicate() {
 @Override
 public boolean test(Integer integer) throws Exception {
 return integer % 2 == 0;
 }
 }) Solution :

Slide 52

Slide 52 text

Distinct “suppress duplicate items emitted by an Observable”

Slide 53

Slide 53 text

Distinct

Slide 54

Slide 54 text

Check it Out! via-Hedwig Checkout commit : “filterrum, distincto" git checkout

Slide 55

Slide 55 text

Input : Observable.fromIterable( Arrays.asList(1, 1, 2, 3, 2)); //TODO Print all distinct numbers Distinct

Slide 56

Slide 56 text

Solution : Distinct Observable.fromIterable(Arrays.asList(1, 1, 2, 3, 2)) .distinct()

Slide 57

Slide 57 text

Take “emit only the first n items emitted by an Observable”

Slide 58

Slide 58 text

Take

Slide 59

Slide 59 text

Check it Out! via-Hedwig Checkout commit : “distincto, takeo" git checkout

Slide 60

Slide 60 text

Take Input : Observable.range(0,10); //TODO Print only first five

Slide 61

Slide 61 text

Take Solution : Observable.range(0, 10) .take(5)

Slide 62

Slide 62 text

Skip “suppress the first n items emitted by an Observable”

Slide 63

Slide 63 text

Skip

Slide 64

Slide 64 text

Check it Out! via-Hedwig Checkout commit : “takeo, skippum" git checkout

Slide 65

Slide 65 text

Skip Input : Observable.range(0,10); //TODO Print all except first three

Slide 66

Slide 66 text

Skip Solution : Observable.range(0, 10) .skip(3)

Slide 67

Slide 67 text

TakeUntil “discard any items emitted by an Observable after a second Observable emits an item or terminates"

Slide 68

Slide 68 text

TakeUntil

Slide 69

Slide 69 text

Check it Out! via-Hedwig Checkout commit : “skippum, takun til" git checkout

Slide 70

Slide 70 text

TakeUntil Input : Observable.interval(100, TimeUnit.MILLISECONDS); Observable.timer(250, TimeUnit.MILLISECONDS); //TODO Print all values till 250 milliseconds

Slide 71

Slide 71 text

TakeUntil Solution : Observable.interval(100, TimeUnit.MILLISECONDS) .takeUntil(Observable.timer(250, TimeUnit.MILLISECONDS)))

Slide 72

Slide 72 text

Reduc-to “apply a function to each item emitted by an Observable, sequentially, and emit the final value”

Slide 73

Slide 73 text

Reduc-to

Slide 74

Slide 74 text

Check it Out! via-Hedwig Checkout commit : “takun, reducto" git checkout

Slide 75

Slide 75 text

Input : Observable.fromIterable(Arrays.asList( "Color : Red", "Size : M", "Occasion : Casual", "Type : T-Shirt")); //TODO Concatenate filters to send to API
 Desired Output : "Color : Red | Size : M | Occasion : Casual | Type : T-Shirt"
 Reduc-to

Slide 76

Slide 76 text

Reduc-to Solution : inputValues
 .reduce(new BiFunction() {
 @Override
 public String apply(String old, String value) throws Exception {
 return old + " | " + value;
 }
 })
 .defaultIfEmpty("No item")
 .toObservable()

Slide 77

Slide 77 text

Map Transforms every element of a collection of items.

Slide 78

Slide 78 text

Map “Transform the items emitted by an Observable by applying a function to each item” - source Transforms every element of a collection of items.

Slide 79

Slide 79 text

Map-io Observable Map Observable 1 2 3 5 10 15 4 20

Slide 80

Slide 80 text

Check it Out! via-Hedwig Checkout commit : “reducto, mapio” git checkout

Slide 81

Slide 81 text

Input : Observable.intervalRange( 1, 10, 100, 500, TimeUnit.MILLISECONDS); //TODO Print multiples of 5
 Map-io

Slide 82

Slide 82 text

Map-io Solution : Observable.intervalRange(1, 10, 100, 500, TimeUnit.MILLISECONDS) .map(new Function() {
 @Override
 public Long apply(Long aLong) throws Exception {
 return aLong * 5;
 }
 })

Slide 83

Slide 83 text

FlatMap Transforms every element of a collection into another collection of items and combines them into a single collection.

Slide 84

Slide 84 text

FlatMap “Transform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable” - source Transforms every element of a collection into another collection of items and combines them into a single collection.

Slide 85

Slide 85 text

FlatMap-ium Observable FlatMap Observable Hello World How Are You? Hello World How Are You?

Slide 86

Slide 86 text

Check it Out! via-Hedwig Checkout commit : “mapio, flatmapum" git checkout

Slide 87

Slide 87 text

Input : Observable.fromIterable( Arrays.asList("Hello World!", "How Are You?")); //TODO Print all the words from strings
 Flatmap-um

Slide 88

Slide 88 text

Solution : Observable.fromIterable(Arrays.asList("Hello World!", "How Are You?")) .flatMap(new Function>() {
 @Override
 public ObservableSource apply(String inputString) throws Exception {
 return Observable.fromArray(inputString.split(" "));
 }
 }) Flatmap-um

Slide 89

Slide 89 text

“Part 3” complex operators

Slide 90

Slide 90 text

“Concat-ify” concat() operator “Merge-os” merge() operator VS

Slide 91

Slide 91 text

Concat “Emit the emissions from two or more Observables without interleaving them” source “Combine multiple Observables into one by merging their emissions” source Merge

Slide 92

Slide 92 text

Concat Merge 1 2 3 4 8 9 1 2 3 4 8 9 1 2 3 4 8 9 1 2 3 4 8 9 Concat-ify Merge-os

Slide 93

Slide 93 text

Fictional Problem (Snape’s Assignment) • Professor Snape has requested all students to write an essay on werewolves. • The students who will turn in the essay first will get more points than the ones submitting later. • Students are divided into four house observables : • GryffindorObservable (G), • SlytherinObservable (S), • HufflepuffObservable (H) and • RavenclawObservable(R)).

Slide 94

Slide 94 text

Observable R1 R2 H1 H2 Observable Observable G1 G2 S1 S2 Observable Snape’s Assignment - Submission

Slide 95

Slide 95 text

Snape’s Assignment - Draco’s trick S1 S2 H1 H2 R1 R2 G1 G2 Concat-ify Observable R1 R2 H1 H2 Observable Observable G1 G2 S1 S2 Observable

Slide 96

Slide 96 text

Check it Out! via-Hedwig Checkout commit : “Start of Part 3, Assignment Evaluator" git checkout

Slide 97

Slide 97 text

Draco’s Trick - Concat-ify Input : gryffindorObservable & slytherinObservable //TODO Concat the observables

Slide 98

Slide 98 text

Draco’s Trick - Concat-ify Solution : slytherinObservable.
 concatWith(gryffindorObservable)

Slide 99

Slide 99 text

Guess who is not so pleased?

Slide 100

Slide 100 text

Guess who is not so pleased? YES!

Slide 101

Slide 101 text

Guess who is not so pleased? YES! Poor Hermione

Slide 102

Slide 102 text

Snape’s Assignment - Hermione’s fix G1 S1 G2 R1 H1 S2 R2 H2 Merge-os Observable R1 R2 H1 H2 Observable Observable G1 G2 S1 S2 Observable

Slide 103

Slide 103 text

Draco’s Trick - Concat-ify Input : gryffindorObservable & slytherinObservable //TODO Merge the observables

Slide 104

Slide 104 text

Draco’s Trick - Concat-ify Solution : gryffindorObservable.
 mergeWith(slytherinObservable)

Slide 105

Slide 105 text

The Battle

Slide 106

Slide 106 text

Fictional Problem (The Battle) • Dumbledore’s army (Harry, Hermione, Ron and others) • Death Eaters (Lucius Malfoy, Bellatrix Lestrange and others) • Each team is casting lethal spells against the other team. • Dumbledore’s army is not as experienced as the Death Eaters. • Spells produced by Death Eaters is overwhelming the Dumbledore’s army (consumer).

Slide 107

Slide 107 text

Check it Out! via-Hedwig Checkout commit : “The Battle” git checkout

Slide 108

Slide 108 text

The Battle Input : Observable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Run the code.

Slide 109

Slide 109 text

The Battle Input : Observable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Limit the number of inputs to 129


Slide 110

Slide 110 text

The Battle Solution : Observable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)

Slide 111

Slide 111 text

“Buffer-undum” buffer() operator

Slide 112

Slide 112 text

Buffer Buffer small chunks of items and emit them instead of emitting one item at a time.

Slide 113

Slide 113 text

Buffer Buffer small chunks of items and emit them instead of emitting one item at a time. “Periodically gather items emitted by an Observable into bundles and emit these bundles rather than emitting the items one at a time" - source

Slide 114

Slide 114 text

Buffer-undum Buffer Observable 1 2 3 4 Observable 1 2 3 4

Slide 115

Slide 115 text

Observable Buffer Observable 1 2 3 4 1 2 getSpellsObservable()
 .buffer(2); //count 3 4

Slide 116

Slide 116 text

The Battle Input : Observable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Buffer 10 items and concatenate them to a String


Slide 117

Slide 117 text

The Battle Solution : Observable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)
 .buffer(10)
 .flatMap(new Function, ObservableSource>() {
 @Override
 public ObservableSource apply(List longs) throws Exception {
 return Observable.fromIterable(longs)
 .reduce("", new BiFunction() {
 @Override
 public String apply(String oldString, Long aLong) throws Exception {
 return oldString + "\n" + aLong;
 }
 }).toObservable();
 }
 })

Slide 118

Slide 118 text

The Battle

Slide 119

Slide 119 text

“Debounce-y” debounce() operator

Slide 120

Slide 120 text

Debounce From a list of items emit an item only when, some time has passed since it last emitted anything.

Slide 121

Slide 121 text

Debounce From a list of items emit an item only when, some time has passed since it last emitted anything. “Only emit an item from an Observable if a particular timespan has passed without it emitting another item" - source

Slide 122

Slide 122 text

Debounce-y Debounce Observable 1 2 3 4 Observable 1 2 4

Slide 123

Slide 123 text

Observable 1 2 3 4 Observable 1 2 4 getSpellsObservable()
 .debounce(300, TimeUnit.MILLISECONDS); Debounce

Slide 124

Slide 124 text

Observable 1 2 3 4 Observable 1 2 4 Debounce

Slide 125

Slide 125 text

Observable 1 2 3 4 Observable 1 2 4 LOSSY Debounce

Slide 126

Slide 126 text

The Battle Input : Observable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Use Debounce 1 Microsecond to drop some values


Slide 127

Slide 127 text

The Battle Solution : Observable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)
 .debounce(1, TimeUnit.MICROSECONDS)

Slide 128

Slide 128 text

Observable 1 2 3 4 Observable 1 2 4 PROBLEM SOLVED Debounce

Slide 129

Slide 129 text

Backpressure “Defence Against the Dark Arts”

Slide 130

Slide 130 text

Backpressure Frequency of Producer producing an item is more than the ability of Consumer to consume.

Slide 131

Slide 131 text

Backpressure Frequency of Producer producing an item is more than the ability of Consumer to consume. “Strategies for coping with Observables that produce items more rapidly than their observers consume them” - source

Slide 132

Slide 132 text

Backpressure via-Hedwig GOOD NEWS!

Slide 133

Slide 133 text

Backpressure via-Hedwig Usually you do not have to worry about back pressure in your applications.

Slide 134

Slide 134 text

Backpressure via-Hedwig RxJava 2 introduces Flowable which is an Observable with backpressure support.

Slide 135

Slide 135 text

Backpressure via-Hedwig With RxJava2, Observables do not support backpressure while Flowables do.

Slide 136

Slide 136 text

Check it Out! via-Hedwig Checkout commit : “The Battle Flow” git checkout

Slide 137

Slide 137 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Run the code.

Slide 138

Slide 138 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Limit the number of inputs to 129


Slide 139

Slide 139 text

The Battle Solution : Flowable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)

Slide 140

Slide 140 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO Go inside FlowableInterval class to see where the Exception is thrown


Slide 141

Slide 141 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); • Flowable.interval() method is tagged as @BackpressureSupport(BackpressureKind.ERROR) • ERROR : The operator will emit a MissingBackpressureException if the downstream didn't request enough or in time. • Consumers should consider applying one of the {@code onBackpressureXXX} operators as well.

Slide 142

Slide 142 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO apply onBackpressureBuffer() strategy


Slide 143

Slide 143 text

The Battle Solution : Flowable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)
 .onBackpressureBuffer()

Slide 144

Slide 144 text

The Battle Input : Flowable.interval(1, 1, TimeUnit.MICROSECONDS); //TODO apply onBackpressureDrop() strategy


Slide 145

Slide 145 text

The Battle Solution : Flowable.interval(1, 1, TimeUnit.MICROSECONDS) .take(129)
 .onBackpressureDrop()

Slide 146

Slide 146 text

“Part 4” Threading

Slide 147

Slide 147 text

observeOn vs subscribeOn What are those two?

Slide 148

Slide 148 text

observeOn vs subscribeOn

Slide 149

Slide 149 text

observeOn vs subscribeOn Sorry! I Don’t Know.

Slide 150

Slide 150 text

observeOn vs subscribeOn Let’s see code instead.

Slide 151

Slide 151 text

Check it Out! via-Hedwig Checkout commit : “Part-4, Threading excercise” git checkout

Slide 152

Slide 152 text

observeOn vs subscribeOn //TODO Uncomment


Slide 153

Slide 153 text

observeOn Default Flow - No ObserveOn

Slide 154

Slide 154 text

observeOn With ObserveOn

Slide 155

Slide 155 text

“Part 5” Testing

Slide 156

Slide 156 text

Check it Out! via-Hedwig Checkout commit : “Testing Emptiness” git checkout

Slide 157

Slide 157 text

EmptyPresenterTest //TODO test view.append() was called once. - to print Complete.

Slide 158

Slide 158 text

EmptyPresenterTest verify(view, times(1)).append("Completed.");
 Solution :

Slide 159

Slide 159 text

Check it Out! via-Hedwig Checkout commit : “Testing Neverland” git checkout

Slide 160

Slide 160 text

NeverPresenterTest //TODO test view.append() was called 0 times. - never.

Slide 161

Slide 161 text

Solution : verify(view, times(0)).append(anyString()); NeverPresenterTest

Slide 162

Slide 162 text

Check it Out! via-Hedwig Checkout commit : “TestObserver and TestSubscriber” git checkout

Slide 163

Slide 163 text

testGetFluxWeed() - TestObserver //TODO Create a TestObserver
 
 //TODO subscribe to getFluxWeed()
 
 //TODO tell observer to wait for terminal event
 
 //TODO assert there are no errors
 
 //TODO assert we received onComplete

Slide 164

Slide 164 text

Solution : //TODO Create a TestObserver
 TestObserver testObserver = TestObserver.create();
 //TODO subscribe to getFluxWeed()
 magicalDataSource.getFluxWeed().subscribe(testObserver);
 //TODO tell observer to wait for terminal event
 testObserver.awaitTerminalEvent();
 //TODO assert there are no errors
 testObserver.assertNoErrors();
 //TODO assert we received onComplete
 testObserver.assertComplete(); testGetFluxWeed() - TestObserver

Slide 165

Slide 165 text

testGetFluxWeedFlowable() - TestObserver //TODO Create a TestSubscriber
 
 //TODO subscribe to getFluxWeed()
 
 //TODO tell subscriber to wait for terminal event
 
 //TODO assert there are no errors
 
 //TODO assert we received onComplete

Slide 166

Slide 166 text

Solution : 
 //TODO Create a TestSubscriber
 TestSubscriber testSubscriber = TestSubscriber.create();
 //TODO subscribe to getFluxWeed()
 magicalDataSource.getFluxWeedFlowable().subscribe(testSubscriber);
 //TODO tell subscriber to wait for terminal event
 testSubscriber.awaitTerminalEvent();
 //TODO assert there are no errors
 testSubscriber.assertNoErrors();
 //TODO assert we received onComplete
 testSubscriber.assertComplete(); testGetFluxWeedFlowable() - TestObserver

Slide 167

Slide 167 text

Check it Out! via-Hedwig Checkout commit : “TestObserver and TestSubscriber” git checkout

Slide 168

Slide 168 text

CONGRATULATIONS! On Completing the code-lab!

Slide 169

Slide 169 text

• Learn by practice. • Make RxJava your friend and not a foe. • Learn by examples - Kaushik Gopal RxJava. https://github.com/kaushikgopal/RxJava-Android-Samples • Codelab - Full Extended Text version (coming soon on) : https://github.com/ragdroid/rxify/tree/codelab • My Medium blogs for more details. https://medium.com/@ragdroid What’s Next

Slide 170

Slide 170 text

Acknowledgements via-Hedwig The terms lossy and lossless have been inspired from the post here.

Slide 171

Slide 171 text

Acknowledgements via-Hedwig Technical Definitions have been taken from reactivex.io.

Slide 172

Slide 172 text

Acknowledgements via-Hedwig Part 1 and 2 examples inspired from Intro-to-Rx book.

Slide 173

Slide 173 text

Acknowledgements via-Hedwig observeOn diagrams from this article.

Slide 174

Slide 174 text

Thank You