Slide 1

Slide 1 text

Error Handling in RxJava DroidKaigi 2017 yuyakaido

Slide 2

Slide 2 text

ࣗݾ঺հ • ւ౻༏໻ʢ͔͍Ͳ͏Ώ͏΍ʣ • AndroidΤϯδχΞ yuyakaido

Slide 3

Slide 3 text

ձࣾ঺հ • גࣜձࣾΤ΢ϨΧ • ࣗࣾΞϓϦͷاըɾ։ൃɾӡӦ • ΦϯϥΠϯσʔςΟϯά • Χοϓϧίϛϡχέʔγϣϯ

Slide 4

Slide 4 text

ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ

Slide 5

Slide 5 text

ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ • OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢

Slide 6

Slide 6 text

ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ • OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢

Slide 7

Slide 7 text

ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ • OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢

Slide 8

Slide 8 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 9

Slide 9 text

໨࣍ɿجຊฤ • αϯϓϧɿެࣜΞϓϦͷContributorΛදࣔ͢Δ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 10

Slide 10 text

໨࣍ɿԠ༻ฤ • جຊฤͰొ৔ͨ͠ΤϥʔϋϯυϦϯάΛ૊Έ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍৔߹͸τʔετΛදࣔ͢Δ

Slide 11

Slide 11 text

໨࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά

Slide 12

Slide 12 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 13

Slide 13 text

RxJavaͷ͓͞Β͍ • Reactive Extension for Java • ඇಉظετϦʔϜ • σʔλϑϩʔΛఆٛͯ͠ɺมߋΛ఻ൖͤ͞Δ ग़యɿhttp://reactivex.io/

Slide 14

Slide 14 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 15

Slide 15 text

RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • Τϥʔൃੜ࣌ʹϦΧόϦʔΛߦ͏ • onError, onErrorReturn, onErrorResumeNext • Retry • Τϥʔൃੜ࣌ʹresubscribe͢Δ • retry, retryWhen

Slide 16

Slide 16 text

Catch • onError • onErrorReturn • onErrorResumeNext

Slide 17

Slide 17 text

Catch • onError • onErrorReturn • onErrorResumeNext

Slide 18

Slide 18 text

onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ

Slide 19

Slide 19 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 });

Slide 20

Slide 20 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 });

Slide 21

Slide 21 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 });

Slide 22

Slide 22 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 });

Slide 23

Slide 23 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 });

Slide 24

Slide 24 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 }); D/ErrorHandlingInRxJava: onNext

Slide 25

Slide 25 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 }); D/ErrorHandlingInRxJava: onNext

Slide 26

Slide 26 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 }); D/ErrorHandlingInRxJava: onNext

Slide 27

Slide 27 text

onError Observable.create(new Action1>() {
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 }, Emitter.BackpressureMode.NONE)
 .subscribe(new Subscriber() {
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 }); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: Something went wrong

Slide 28

Slide 28 text

onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ • Τϥʔ಺༰͕Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ࢖ͬͯΤϥʔϋϯυϦϯάΛߦ͏

Slide 29

Slide 29 text

Catch • onError • onErrorReturn • onErrorResumeNext

Slide 30

Slide 30 text

onErrorReturn • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹ୅ΘΓͷσʔλΛฦ͢ ग़యɿhttp://reactivex.io/

Slide 31

Slide 31 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());

Slide 32

Slide 32 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());

Slide 33

Slide 33 text

NextThenError public class NextThenError implements Action1> {
 
 @Override
 public void call(Emitter emitter) {
 emitter.onNext("onNext");
 emitter.onError(new RuntimeException("Something went wrong"));
 }
 
 } 1ͭ໨ͷΞΠςϜͱͯ͠ʮonNextʯΛΤϛοτ͢Δ 2ͭ໨ͷΞΠςϜͱͯ͠ʮRuntimeExceptionʯΛΤϛοτ͢Δ

Slide 34

Slide 34 text

LoggingSubscriber public class LoggingSubscriber extends Subscriber {
 
 @Override
 public void onCompleted() {
 Log.d("ErrorHandlingInRxJava", "onCompleted");
 }
 
 @Override
 public void onError(Throwable e) {
 Log.d("ErrorHandlingInRxJava", e.getMessage());
 }
 
 @Override
 public void onNext(String s) {
 Log.d("ErrorHandlingInRxJava", s);
 }
 
 } Observable͔ΒྲྀΕ͖ͯͨΠϕϯτΛϩάʹදࣔ͢Δ

Slide 35

Slide 35 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());

Slide 36

Slide 36 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());

Slide 37

Slide 37 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); onErrorReturn( )

Slide 38

Slide 38 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); onErrorReturn( )

Slide 39

Slide 39 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )

Slide 40

Slide 40 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )

Slide 41

Slide 41 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )

Slide 42

Slide 42 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )

Slide 43

Slide 43 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorReturn onErrorReturn( )

Slide 44

Slide 44 text

onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1() {
 @Override
 public String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorReturn D/ErrorHandlingInRxJava: onCompleted onErrorReturn( )

Slide 45

Slide 45 text

onErrorReturn • Τϥʔ͕ൃੜͨ͠৔߹ʹ୅ΘΓͷσʔλΛฦ͢ • Τϥʔ಺༰͸Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ΋ͱʹ୅ΘΓͷσʔλΛฦ͢ • ΋ͱͷObservable͸Complete͢Δ

Slide 46

Slide 46 text

Catch • onError • onErrorReturn • onErrorResumeNext

Slide 47

Slide 47 text

onErrorResumeNext • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹ୅ΘΓͷObservableΛ ฦ͢ ग़యɿhttp://reactivex.io/

Slide 48

Slide 48 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber());

Slide 49

Slide 49 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber());

Slide 50

Slide 50 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); onErrorResumeNext( )

Slide 51

Slide 51 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); onErrorResumeNext( )

Slide 52

Slide 52 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )

Slide 53

Slide 53 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )

Slide 54

Slide 54 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )

Slide 55

Slide 55 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )

Slide 56

Slide 56 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorResumeNext onErrorResumeNext( )

Slide 57

Slide 57 text

onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorResumeNext(
 new Func1>() {
 @Override
 public Observable extends String> call(
 Throwable throwable) {
 return Observable.just("onErrorResumeNext");
 }
 }
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorResumeNext D/ErrorHandlingInRxJava: onCompleted onErrorResumeNext( )

Slide 58

Slide 58 text

onErrorResumeNext • Τϥʔ͕ൃੜͨ͠৔߹ʹ୅ΘΓͷObservableΛฦ͢ • Τϥʔ಺༰͸Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ΋ͱʹ୅ΘΓͷObservableΛฦ͢ • ΋ͱͷObservable͸Complete͢Δ

Slide 59

Slide 59 text

Retry • retry • retryWhen

Slide 60

Slide 60 text

Retry • retry • retryWhen

Slide 61

Slide 61 text

retry • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹresubscribe͢Δ ग़యɿhttp://reactivex.io/

Slide 62

Slide 62 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber());

Slide 63

Slide 63 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber());

Slide 64

Slide 64 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); retry(1)

Slide 65

Slide 65 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); retry(1)

Slide 66

Slide 66 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

Slide 67

Slide 67 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

Slide 68

Slide 68 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

Slide 69

Slide 69 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1) subscribe

Slide 70

Slide 70 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1) subscribe

Slide 71

Slide 71 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext retry(1) subscribe

Slide 72

Slide 72 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext retry(1) subscribe

Slide 73

Slide 73 text

retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: Something went wrong retry(1) subscribe

Slide 74

Slide 74 text

retry • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹresubscribe͢Δ • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹଈ࠲ʹresubscribe͢Δ • Ҿ਺Ͱճ਺Λࢦఆ͢Δ͜ͱ͕ग़དྷΔ

Slide 75

Slide 75 text

Retry • retry • retryWhen

Slide 76

Slide 76 text

retryWhen • resubscribe͢Δ৚݅Λࡉ੍͔͘ޚͰ͖Δ • resubscribe͢ΔͨΊͷτϦΨʔͱͳΔObservableΛฦ͢ • τϦΨʔʹNextΛΤϛοτ͢Δͱresubscribe • τϦΨʔʹCompleteΛΤϛοτ͢ΔͱComplete • τϦΨʔʹErrorΛΤϛοτ͢ΔͱError ग़యɿhttp://reactivex.io/

Slide 77

Slide 77 text

retryWhen • ϚʔϒϧμΠΞάϥϜͰߟ͑ͯΈΔ ग़యɿhttp://reactivex.io/

Slide 78

Slide 78 text

retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

Slide 79

Slide 79 text

retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

Slide 80

Slide 80 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

Slide 81

Slide 81 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

Slide 82

Slide 82 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 83

Slide 83 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 84

Slide 84 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 85

Slide 85 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 86

Slide 86 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 87

Slide 87 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 88

Slide 88 text

Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: Something went wrong retryWhen ( )

Slide 89

Slide 89 text

retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

Slide 90

Slide 90 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

Slide 91

Slide 91 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

Slide 92

Slide 92 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 93

Slide 93 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 94

Slide 94 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 95

Slide 95 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 96

Slide 96 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 97

Slide 97 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 98

Slide 98 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 99

Slide 99 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 100

Slide 100 text

Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onCompleted retryWhen ( )

Slide 101

Slide 101 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber());

Slide 102

Slide 102 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber());

Slide 103

Slide 103 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 104

Slide 104 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 105

Slide 105 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 106

Slide 106 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )

Slide 107

Slide 107 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 108

Slide 108 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 109

Slide 109 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 110

Slide 110 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( )

Slide 111

Slide 111 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( ) subscribe

Slide 112

Slide 112 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retryWhen ( ) subscribe

Slide 113

Slide 113 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext retryWhen ( ) subscribe

Slide 114

Slide 114 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext retryWhen ( ) subscribe

Slide 115

Slide 115 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext retryWhen ( ) subscribe

Slide 116

Slide 116 text

࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 
 Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onCompleted retryWhen ( ) subscribe

Slide 117

Slide 117 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 118

Slide 118 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 119

Slide 119 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 120

Slide 120 text

ΤϥʔΛτʔετͰදࣔ͢Δ • Ϣʔεέʔε • ΤϥʔϝοηʔδΛදࣔ͢Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ • onError

Slide 121

Slide 121 text

ΤϥʔΛτʔετͰදࣔ͢Δ

Slide 122

Slide 122 text

ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors()
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber>() {
 @Override
 public void onCompleted() {}
 
 @Override
 public void onError(Throwable e) {
 Toast.makeText(MainActivity.this, e.getMessage(),
 Toast.LENGTH_SHORT).show();
 }
 
 @Override
 public void onNext(List githubContributors) {
 // Write your awesome logic
 }
 });

Slide 123

Slide 123 text

ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors()
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber>() {
 @Override
 public void onCompleted() {}
 
 @Override
 public void onError(Throwable e) {
 Toast.makeText(MainActivity.this, e.getMessage(),
 Toast.LENGTH_SHORT).show();
 }
 
 @Override
 public void onNext(List githubContributors) {
 // Write your awesome logic
 }
 });

Slide 124

Slide 124 text

ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors()
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber>() {
 @Override
 public void onCompleted() {}
 
 @Override
 public void onError(Throwable e) {
 Toast.makeText(MainActivity.this, e.getMessage(),
 Toast.LENGTH_SHORT).show();
 }
 
 @Override
 public void onNext(List githubContributors) {
 // Write your awesome logic
 }
 });

Slide 125

Slide 125 text

ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors()
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber>() {
 @Override
 public void onCompleted() {}
 
 @Override
 public void onError(Throwable e) {
 Toast.makeText(MainActivity.this, e.getMessage(),
 Toast.LENGTH_SHORT).show();
 }
 
 @Override
 public void onNext(List githubContributors) {
 // Write your awesome logic
 }
 });

Slide 126

Slide 126 text

ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors()
 .subscribeOn(Schedulers.io())
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(new Subscriber>() {
 @Override
 public void onCompleted() {}
 
 @Override
 public void onError(Throwable e) {
 Toast.makeText(MainActivity.this, e.getMessage(),
 Toast.LENGTH_SHORT).show();
 }
 
 @Override
 public void onNext(List githubContributors) {
 // Write your awesome logic
 }
 });

Slide 127

Slide 127 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 128

Slide 128 text

୅ΘΓͷσʔλΛදࣔ͢Δ • Ϣʔεέʔε • αʔόʔ͔Βσʔλ͕औಘͰ͖ͳ͔ͬͨ৔߹ʹɺΩϟο γϡ͍ͯ͠ΔσʔλΛදࣔ͢Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ • ୅ΘΓʹΩϟογϡ͔ΒऔΓग़ͨ͠σʔλΛྲྀ͢ • onErrorReturn

Slide 129

Slide 129 text

୅ΘΓͷσʔλΛදࣔ͢Δ

Slide 130

Slide 130 text

୅ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 131

Slide 131 text

୅ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 132

Slide 132 text

୅ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 133

Slide 133 text

୅ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 134

Slide 134 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 135

Slide 135 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • Ϣʔεέʔε • αʔόʔ͕ฦͨ͠ΤϥʔίʔυʹΑͬͯॲཧΛ෼ذ͢ Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ • ΤϥʔͷछྨΛ΋ͱʹॲཧΛ෼ذ͢Δ • onErrorResumeNext

Slide 136

Slide 136 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 137

Slide 137 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 138

Slide 138 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 139

Slide 139 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 140

Slide 140 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 141

Slide 141 text

ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 142

Slide 142 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 143

Slide 143 text

ϦτϥΠ͢Δ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠৔߹ʹϦτϥΠ͢Δ • ࣮૷ํ਑ • ObservableʹΤϥʔ͕ྲྀΕͨ৔߹ʹresubscribe͢Δ • retry

Slide 144

Slide 144 text

ϦτϥΠ͢Δ client.getDroidKaigiContributors()
 .retry(3);

Slide 145

Slide 145 text

جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ

Slide 146

Slide 146 text

ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠৔߹ʹSnackbarΛදࣔ͠ ͯɺϦτϥΠ͢Δ͔ΛਘͶΔ • ࣮૷ํ਑ • ObservableʹΤϥʔ͕ྲྀΕͨΒSnackbarΛදࣔ͢Δ • Ϣʔβʔ͕ϦτϥΠΛԡͨ͠৔߹ʹresubscribe͢Δ

Slide 147

Slide 147 text

ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ

Slide 148

Slide 148 text

ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .retryWhen(observable -> observable.flatMap(throwable ->
 Observable.create(emitter -> {
 Snackbar snackbar = Snackbar.make(
 getView(), "Retry?", Snackbar.LENGTH_INDEFINITE);
 snackbar.setAction("Yes", view -> emitter.onNext(null));
 snackbar.show();
 }, Emitter.BackpressureMode.NONE))
 )

Slide 149

Slide 149 text

ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .retryWhen(observable -> observable.flatMap(throwable ->
 Observable.create(emitter -> {
 Snackbar snackbar = Snackbar.make(
 getView(), "Retry?", Snackbar.LENGTH_INDEFINITE);
 snackbar.setAction("Yes", view -> emitter.onNext(null));
 snackbar.show();
 }, Emitter.BackpressureMode.NONE))
 )

Slide 150

Slide 150 text

ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .retryWhen(observable -> observable.flatMap(throwable ->
 Observable.create(emitter -> {
 Snackbar snackbar = Snackbar.make(
 getView(), "Retry?", Snackbar.LENGTH_INDEFINITE);
 snackbar.setAction("Yes", view -> emitter.onNext(null));
 snackbar.show();
 }, Emitter.BackpressureMode.NONE))
 )

Slide 151

Slide 151 text

ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .retryWhen(observable -> observable.flatMap(throwable ->
 Observable.create(emitter -> {
 Snackbar snackbar = Snackbar.make(
 getView(), "Retry?", Snackbar.LENGTH_INDEFINITE);
 snackbar.setAction("Yes", view -> emitter.onNext(null));
 snackbar.show();
 }, Emitter.BackpressureMode.NONE))
 )

Slide 152

Slide 152 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 153

Slide 153 text

Ԡ༻ฤ • جຊฤͰొ৔ͨ͠ΤϥʔϋϯυϦϯάΛ૊Έ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍৔߹͸τʔετΛදࣔ͢Δ

Slide 154

Slide 154 text

Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 155

Slide 155 text

Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 156

Slide 156 text

Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 157

Slide 157 text

Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 158

Slide 158 text

Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorReturn(new Func1>() {
 @Override
 public List call(Throwable throwable) {
 return dao.findAll(); // DB͔Βऔಘ
 }
 });

Slide 159

Slide 159 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 160

Slide 160 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 161

Slide 161 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 162

Slide 162 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 163

Slide 163 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 164

Slide 164 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 165

Slide 165 text

Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ
 .retry(3)
 .doOnNext(new Action1>() {
 @Override
 public void call(List githubContributors) {
 dao.insertAll(githubContributors); // DBʹอଘ
 }
 })
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (dao.exists()) {
 return Observable.just(dao.findAll());
 }
 return Observable.error(throwable);
 }
 }
 );

Slide 166

Slide 166 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 167

Slide 167 text

໨࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά

Slide 168

Slide 168 text

RetrofitͷΤϥʔϋϯυϦϯά • جຊฤͰ঺հͨ͠ʮΤϥʔͷछྨͰॲཧΛ෼ذ͢ΔʯΛ શAPIʹ࢓ࠐΈ͍ͨ client.getDroidKaigiContributors()
 .onErrorResumeNext(
 new Func1>>() {
 @Override
 public Observable extends List> call(
 Throwable throwable) {
 if (throwable instanceof AccessTokenExpiredException) {
 // ϩάΞ΢τ
 }
 
 if (throwable instanceof MaintenanceModeException) {
 // ϝϯςφϯεϞʔυ
 }
 
 return Observable.error(throwable);
 }
 }
 );

Slide 169

Slide 169 text

RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹ࢓ࠐΉʹ͸ • ίϐϖ • Ϋϥεʹ੾Γग़ͯ͠ɺͦΕΛશAPIʹ࢓ࠐΉ

Slide 170

Slide 170 text

RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹ࢓ࠐΉʹ͸ • ίϐϖ • Ϋϥεʹ੾Γग़ͯ͠ɺͦΕΛશAPIʹ࢓ࠐΉ • RxJavaCallAdapterFactoryͷ֦ு

Slide 171

Slide 171 text

RetrofitͷΤϥʔϋϯυϦϯά public class RxJavaErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
 
 public static RxJavaErrorHandlingCallAdapterFactory create() {
 return new RxJavaErrorHandlingCallAdapterFactory();
 }
 
 private final CallAdapter.Factory original = RxJavaCallAdapterFactory.create();
 
 @Override
 public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
 return new RxJavaCallAdapterWrapper(original.get(returnType, annotations, retrofit));
 }
 
 private static class RxJavaCallAdapterWrapper
 implements CallAdapter> {
 private final CallAdapter original;
 
 public RxJavaCallAdapterWrapper(CallAdapter original) {
 this.original = original;
 }
 
 @Override
 public Type responseType() {
 return original.responseType();
 }
 
 @Override
 public Observable> adapt(Call call) {
 return ((Observable>) original.adapt(call))
 .onErrorResumeNext(new ErrorHandler<>());
 }
 }
 }

Slide 172

Slide 172 text

RetrofitͷΤϥʔϋϯυϦϯά public class RxJavaErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
 
 public static RxJavaErrorHandlingCallAdapterFactory create() {
 return new RxJavaErrorHandlingCallAdapterFactory();
 }
 
 private final CallAdapter.Factory original = RxJavaCallAdapterFactory.create();
 
 @Override
 public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
 return new RxJavaCallAdapterWrapper(original.get(returnType, annotations, retrofit));
 }
 
 private static class RxJavaCallAdapterWrapper
 implements CallAdapter> {
 private final CallAdapter original;
 
 public RxJavaCallAdapterWrapper(CallAdapter original) {
 this.original = original;
 }
 
 @Override
 public Type responseType() {
 return original.responseType();
 }
 
 @Override
 public Observable> adapt(Call call) {
 return ((Observable>) original.adapt(call))
 .onErrorResumeNext(new ErrorHandler<>());
 }
 }
 }

Slide 173

Slide 173 text

RetrofitͷΤϥʔϋϯυϦϯά private static class RxJavaCallAdapterWrapper
 implements CallAdapter> {
 private final CallAdapter original;
 
 public RxJavaCallAdapterWrapper(CallAdapter original) {
 this.original = original;
 }
 
 @Override
 public Type responseType() {
 return original.responseType();
 }
 
 @Override
 public Observable> adapt(Call call) {
 return ((Observable>) original.adapt(call))
 .onErrorResumeNext(new ErrorHandler<>());
 }
 }

Slide 174

Slide 174 text

RetrofitͷΤϥʔϋϯυϦϯά private static class RxJavaCallAdapterWrapper
 implements CallAdapter> {
 private final CallAdapter original;
 
 public RxJavaCallAdapterWrapper(CallAdapter original) {
 this.original = original;
 }
 
 @Override
 public Type responseType() {
 return original.responseType();
 }
 
 @Override
 public Observable> adapt(Call call) {
 return ((Observable>) original.adapt(call))
 .onErrorResumeNext(new ErrorHandler<>());
 }
 }

Slide 175

Slide 175 text

RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder()
 .baseUrl(BuildConfig.API_ENDPOINT)
 .client(okHttpClient)
 .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application))
 .addConverterFactory(GsonConverterFactory.create())
 .build()

Slide 176

Slide 176 text

RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder()
 .baseUrl(BuildConfig.API_ENDPOINT)
 .client(okHttpClient)
 .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application))
 .addConverterFactory(GsonConverterFactory.create())
 .build()

Slide 177

Slide 177 text

໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ • ࣮ફฤ • ·ͱΊ

Slide 178

Slide 178 text

·ͱΊ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • onError, onErrorReturn, onErrorResumeNext • Retry • retry, retryWhen

Slide 179

Slide 179 text

·ͱΊ • جૅฤ • ΤϥʔΛτʔετͰදࣔ͢ΔɿonError • ୅ΘΓͷσʔλΛදࣔ͢ΔɿonErrorReturn • ΤϥʔͷछྨͰॲཧΛ෼ذ͢ΔɿonErrorResumeNext • ϦτϥΠ͢Δɿretry • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔɿretryWhen

Slide 180

Slide 180 text

·ͱΊ • Ԡ༻ฤ • ϦτϥΠˍΩϟογϡɿretry, onErrorReturn • ϦτϥΠˍΩϟογϡˍτʔετɿretry, onErrorReturn, onError

Slide 181

Slide 181 text

·ͱΊ • ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά • RxJavaCallAdapterFactoryͷ֦ு

Slide 182

Slide 182 text

Thank you :) Credit: NASA Earth Observatory/NOAA NGDC