Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
droidkaigi-2017
Yuya Kaido
March 10, 2017
Programming
12
5.9k
droidkaigi-2017
Yuya Kaido
March 10, 2017
Tweet
Share
More Decks by Yuya Kaido
See All by Yuya Kaido
droidkaigi-2019
yuyakaido
7
3.6k
matching-dev-meetup-1
yuyakaido
1
170
minami-aoyama-night-6
yuyakaido
1
990
eureka-meetup-10
yuyakaido
0
660
droidkaigi-2018
yuyakaido
4
4.2k
navitime-eureka-1
yuyakaido
0
48
retty-tech-cafe-8
yuyakaido
0
150
mti-eureka-tech-beer
yuyakaido
0
380
potatotips-33
yuyakaido
2
530
Other Decks in Programming
See All in Programming
GitHubのユーザー名を変更した後のあれこれ
tahia910
0
130
Why Airflow? & What's new in Airflow 2.3?
kaxil
0
110
VisualProgramming_GoogleHome_LINE
nearmugi
1
230
Managing Error Messages with your Oracle Database REST APIs
thatjeffsmith
0
130
Angular‘s Future without NgModules: Architectures with Standalone Components @enterJS
manfredsteyer
PRO
0
230
即、New Relic / New Relic NOW!
uzulla
0
330
Amazon ECSのネットワーク関連コストの話
msato
0
640
GoogleI/O2022 LT報告会資料
shinsukefujita1126
0
330
Licences open source : entre guerre de clochers et radicalité
pylapp
2
490
設計の学び方:自分流のススメ
masuda220
PRO
7
2.5k
Modern Android Developer ~ 안내서
pluu
1
630
The strategies behind ddd – AdeoDevSummit 2022
lilobase
PRO
4
250
Featured
See All Featured
Visualization
eitanlees
125
11k
Building a Scalable Design System with Sketch
lauravandoore
448
30k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
236
1M
Pencils Down: Stop Designing & Start Developing
hursman
112
9.8k
How To Stay Up To Date on Web Technology
chriscoyier
780
250k
Adopting Sorbet at Scale
ufuk
63
7.6k
Web development in the modern age
philhawksworth
197
9.3k
Put a Button on it: Removing Barriers to Going Fast.
kastner
56
2.3k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
11
4.7k
From Idea to $5000 a Month in 5 Months
shpigford
373
44k
Robots, Beer and Maslow
schacon
152
7.1k
The Illustrated Children's Guide to Kubernetes
chrisshort
15
36k
Transcript
Error Handling in RxJava DroidKaigi 2017 yuyakaido
ࣗݾհ • ւ౻༏ʢ͔͍Ͳ͏Ώ͏ʣ • AndroidΤϯδχΞ yuyakaido
ձࣾհ • גࣜձࣾΤϨΧ • ࣗࣾΞϓϦͷاըɾ։ൃɾӡӦ • ΦϯϥΠϯσʔςΟϯά • Χοϓϧίϛϡχέʔγϣϯ
ຊηογϣϯͰ͓͍͑ͨ͜͠ͱ
ຊηογϣϯͰ͓͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯͦ͘͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperatorଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔ • RxJavaΛΘͣʹ࣮͢Δ߹ͱൺֱͨ͠ϝϦοτʁ •
OperatorΛΈ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮͢Δ͜ͱ͕ग़དྷ·͢
ຊηογϣϯͰ͓͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯͦ͘͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperatorଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔ • RxJavaΛΘͣʹ࣮͢Δ߹ͱൺֱͨ͠ϝϦοτʁ •
OperatorΛΈ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮͢Δ͜ͱ͕ग़དྷ·͢
ຊηογϣϯͰ͓͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯͦ͘͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperatorଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔ • RxJavaΛΘͣʹ࣮͢Δ߹ͱൺֱͨ͠ϝϦοτʁ •
OperatorΛΈ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮͢Δ͜ͱ͕ग़དྷ·͢
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
࣍ɿجຊฤ • αϯϓϧɿެࣜΞϓϦͷContributorΛදࣔ͢Δ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ •
ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
࣍ɿԠ༻ฤ • جຊฤͰొͨ͠ΤϥʔϋϯυϦϯάΛΈ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ •
Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍߹τʔετΛදࣔ͢Δ
࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
RxJavaͷ͓͞Β͍ • Reactive Extension for Java • ඇಉظετϦʔϜ • σʔλϑϩʔΛఆٛͯ͠ɺมߋΛൖͤ͞Δ
ग़యɿhttp://reactivex.io/
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • Τϥʔൃੜ࣌ʹϦΧόϦʔΛߦ͏ • onError, onErrorReturn, onErrorResumeNext •
Retry • Τϥʔൃੜ࣌ʹresubscribe͢Δ • retry, retryWhen
Catch • onError • onErrorReturn • onErrorResumeNext
Catch • onError • onErrorReturn • onErrorResumeNext
onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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); } });
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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); } });
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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); } });
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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); } });
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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); } });
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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
onError Observable.create(new Action1<Emitter<String>>() { @Override public void call(Emitter<String> emitter) {
emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } }, Emitter.BackpressureMode.NONE) .subscribe(new Subscriber<String>() { @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
onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ • Τϥʔ༰͕Throwableͱͯ͠͞ΕΔ • ThrowableΛͬͯΤϥʔϋϯυϦϯάΛߦ͏
Catch • onError • onErrorReturn • onErrorResumeNext
onErrorReturn • Τϥʔ͕Τϛοτ͞Εͨ߹ʹΘΓͷσʔλΛฦ͢ ग़యɿhttp://reactivex.io/
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber());
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber());
NextThenError public class NextThenError implements Action1<Emitter<String>> { @Override public
void call(Emitter<String> emitter) { emitter.onNext("onNext"); emitter.onError(new RuntimeException("Something went wrong")); } } 1ͭͷΞΠςϜͱͯ͠ʮonNextʯΛΤϛοτ͢Δ 2ͭͷΞΠςϜͱͯ͠ʮRuntimeExceptionʯΛΤϛοτ͢Δ
LoggingSubscriber public class LoggingSubscriber extends Subscriber<String> { @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͔ΒྲྀΕ͖ͯͨΠϕϯτΛϩάʹදࣔ͢Δ
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber());
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber());
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorReturn onErrorReturn( )
onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorReturn(new Func1<Throwable, String>() { @Override public
String call(Throwable throwable) { return "onErrorReturn"; } }) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorReturn D/ErrorHandlingInRxJava: onCompleted onErrorReturn( )
onErrorReturn • Τϥʔ͕ൃੜͨ͠߹ʹΘΓͷσʔλΛฦ͢ • Τϥʔ༰Throwableͱͯ͠͞ΕΔ • ThrowableΛͱʹΘΓͷσʔλΛฦ͢ • ͱͷObservableComplete͢Δ
Catch • onError • onErrorReturn • onErrorResumeNext
onErrorResumeNext • Τϥʔ͕Τϛοτ͞Εͨ߹ʹΘΓͷObservableΛ ฦ͢ ग़యɿhttp://reactivex.io/
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber());
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber());
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @Override public Observable<? extends String> call( Throwable throwable) { return Observable.just("onErrorResumeNext"); } } ) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onErrorResumeNext onErrorResumeNext( )
onErrorResumeNext Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .onErrorResumeNext( new Func1<Throwable, Observable<? extends String>>()
{ @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( )
onErrorResumeNext • Τϥʔ͕ൃੜͨ͠߹ʹΘΓͷObservableΛฦ͢ • Τϥʔ༰Throwableͱͯ͠͞ΕΔ • ThrowableΛͱʹΘΓͷObservableΛฦ͢ • ͱͷObservableComplete͢Δ
Retry • retry • retryWhen
Retry • retry • retryWhen
retry • Τϥʔ͕Τϛοτ͞Εͨ߹ʹresubscribe͢Δ ग़యɿhttp://reactivex.io/
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber());
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber());
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); retry(1)
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); retry(1)
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)
subscribe
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)
subscribe
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava:
onNext retry(1) subscribe
retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retry(1) .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava:
onNext retry(1) subscribe
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
retry • Τϥʔ͕Τϛοτ͞Εͨ߹ʹresubscribe͢Δ • Τϥʔ͕Τϛοτ͞Εͨ߹ʹଈ࠲ʹresubscribe͢Δ • ҾͰճΛࢦఆ͢Δ͜ͱ͕ग़དྷΔ
Retry • retry • retryWhen
retryWhen • resubscribe͢Δ݅Λࡉ੍͔͘ޚͰ͖Δ • resubscribe͢ΔͨΊͷτϦΨʔͱͳΔObservableΛฦ͢ • τϦΨʔʹNextΛΤϛοτ͢Δͱresubscribe • τϦΨʔʹCompleteΛΤϛοτ͢ΔͱComplete •
τϦΨʔʹErrorΛΤϛοτ͢ΔͱError ग़యɿhttp://reactivex.io/
retryWhen • ϚʔϒϧμΠΞάϥϜͰߟ͑ͯΈΔ ग़యɿhttp://reactivex.io/
retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ
retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.flatMap(Observable::error) ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔͷ··ऴྃ͢Δ 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 ( )
retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext retryWhen ( )
Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().ignoreElements() ) .subscribe(new LoggingSubscriber());
D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onCompleted retryWhen ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber());
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber());
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber()); retryWhen ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber()); retryWhen ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber()); retryWhen ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE) .retryWhen(observable -> observable.first().flatMap(throwable ->
Observable.timer(3, TimeUnit.SECONDS) ) ) .subscribe(new LoggingSubscriber()); retryWhen ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
ΤϥʔΛτʔετͰදࣔ͢Δ • Ϣʔεέʔε • ΤϥʔϝοηʔδΛදࣔ͢Δ • ࣮ํ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ •
onError
ΤϥʔΛτʔετͰදࣔ͢Δ
ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @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<GithubContributor> githubContributors) { // Write your awesome logic } });
ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @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<GithubContributor> githubContributors) { // Write your awesome logic } });
ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @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<GithubContributor> githubContributors) { // Write your awesome logic } });
ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @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<GithubContributor> githubContributors) { // Write your awesome logic } });
ΤϥʔΛτʔετͰදࣔ͢Δ githubRepository.getDroidKaigiContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<GithubContributor>>() { @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<GithubContributor> githubContributors) { // Write your awesome logic } });
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
ΘΓͷσʔλΛදࣔ͢Δ • Ϣʔεέʔε • αʔόʔ͔Βσʔλ͕औಘͰ͖ͳ͔ͬͨ߹ʹɺΩϟο γϡ͍ͯ͠ΔσʔλΛදࣔ͢Δ • ࣮ํ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ
• ΘΓʹΩϟογϡ͔ΒऔΓग़ͨ͠σʔλΛྲྀ͢ • onErrorReturn
ΘΓͷσʔλΛදࣔ͢Δ
ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .doOnNext(new Action1<List<GithubContributor>>() { @Override public void
call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .doOnNext(new Action1<List<GithubContributor>>() { @Override public void
call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .doOnNext(new Action1<List<GithubContributor>>() { @Override public void
call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
ΘΓͷσʔλΛදࣔ͢Δ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .doOnNext(new Action1<List<GithubContributor>>() { @Override public void
call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
ΤϥʔͷछྨͰॲཧΛذ͢Δ • Ϣʔεέʔε • αʔόʔ͕ฦͨ͠ΤϥʔίʔυʹΑͬͯॲཧΛذ͢ Δ • ࣮ํ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ
• ΤϥʔͷछྨΛͱʹॲཧΛذ͢Δ • onErrorResumeNext
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
ΤϥʔͷछྨͰॲཧΛذ͢Δ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override
public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
ϦτϥΠ͢Δ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠߹ʹϦτϥΠ͢Δ • ࣮ํ • ObservableʹΤϥʔ͕ྲྀΕͨ߹ʹresubscribe͢Δ •
retry
ϦτϥΠ͢Δ client.getDroidKaigiContributors() .retry(3);
جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛذ͢Δ • ϦτϥΠ͢Δ •
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠߹ʹSnackbarΛදࣔ͠ ͯɺϦτϥΠ͢Δ͔ΛਘͶΔ • ࣮ํ • ObservableʹΤϥʔ͕ྲྀΕͨΒSnackbarΛදࣔ͢Δ
• Ϣʔβʔ͕ϦτϥΠΛԡͨ͠߹ʹresubscribe͢Δ
ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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)) )
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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)) )
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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)) )
ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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)) )
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
Ԡ༻ฤ • جຊฤͰొͨ͠ΤϥʔϋϯυϦϯάΛΈ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ •
Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍߹τʔετΛදࣔ͢Δ
Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
Ϣʔεέʔε1ɿϦτϥΠˍΩϟογϡ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorReturn(new Func1<Throwable, List<GithubContributor>>() { @Override public List<GithubContributor> call(Throwable throwable) { return dao.findAll(); // DB͔Βऔಘ } });
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
Ϣʔεέʔε2ɿϦτϥΠˍΩϟογϡˍτʔετ client.getDroidKaigiContributors() // αʔόʔ͔Βऔಘ .retry(3) .doOnNext(new Action1<List<GithubContributor>>() { @Override public
void call(List<GithubContributor> githubContributors) { dao.insertAll(githubContributors); // DBʹอଘ } }) .onErrorResumeNext( new Func1<Throwable, Observable<? extends List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (dao.exists()) { return Observable.just(dao.findAll()); } return Observable.error(throwable); } } );
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά
RetrofitͷΤϥʔϋϯυϦϯά • جຊฤͰհͨ͠ʮΤϥʔͷछྨͰॲཧΛذ͢ΔʯΛ શAPIʹࠐΈ͍ͨ client.getDroidKaigiContributors() .onErrorResumeNext( new Func1<Throwable, Observable<? extends
List<GithubContributor>>>() { @Override public Observable<? extends List<GithubContributor>> call( Throwable throwable) { if (throwable instanceof AccessTokenExpiredException) { // ϩάΞτ } if (throwable instanceof MaintenanceModeException) { // ϝϯςφϯεϞʔυ } return Observable.error(throwable); } } );
RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹࠐΉʹ • ίϐϖ • ΫϥεʹΓग़ͯ͠ɺͦΕΛશAPIʹࠐΉ
RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹࠐΉʹ • ίϐϖ • ΫϥεʹΓग़ͯ͠ɺͦΕΛશAPIʹࠐΉ • RxJavaCallAdapterFactoryͷ֦ு
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<R> implements CallAdapter<R, Observable<?>> { private final CallAdapter<R, ?> original; public RxJavaCallAdapterWrapper(CallAdapter<R, ?> original) { this.original = original; } @Override public Type responseType() { return original.responseType(); } @Override public Observable<?> adapt(Call<R> call) { return ((Observable<?>) original.adapt(call)) .onErrorResumeNext(new ErrorHandler<>()); } } }
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<R> implements CallAdapter<R, Observable<?>> { private final CallAdapter<R, ?> original; public RxJavaCallAdapterWrapper(CallAdapter<R, ?> original) { this.original = original; } @Override public Type responseType() { return original.responseType(); } @Override public Observable<?> adapt(Call<R> call) { return ((Observable<?>) original.adapt(call)) .onErrorResumeNext(new ErrorHandler<>()); } } }
RetrofitͷΤϥʔϋϯυϦϯά private static class RxJavaCallAdapterWrapper<R> implements CallAdapter<R, Observable<?>> { private
final CallAdapter<R, ?> original; public RxJavaCallAdapterWrapper(CallAdapter<R, ?> original) { this.original = original; } @Override public Type responseType() { return original.responseType(); } @Override public Observable<?> adapt(Call<R> call) { return ((Observable<?>) original.adapt(call)) .onErrorResumeNext(new ErrorHandler<>()); } }
RetrofitͷΤϥʔϋϯυϦϯά private static class RxJavaCallAdapterWrapper<R> implements CallAdapter<R, Observable<?>> { private
final CallAdapter<R, ?> original; public RxJavaCallAdapterWrapper(CallAdapter<R, ?> original) { this.original = original; } @Override public Type responseType() { return original.responseType(); } @Override public Observable<?> adapt(Call<R> call) { return ((Observable<?>) original.adapt(call)) .onErrorResumeNext(new ErrorHandler<>()); } }
RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder() .baseUrl(BuildConfig.API_ENDPOINT) .client(okHttpClient) .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application)) .addConverterFactory(GsonConverterFactory.create()) .build()
RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder() .baseUrl(BuildConfig.API_ENDPOINT) .client(okHttpClient) .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application)) .addConverterFactory(GsonConverterFactory.create()) .build()
࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •
࣮ફฤ • ·ͱΊ
·ͱΊ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • onError, onErrorReturn, onErrorResumeNext •
Retry • retry, retryWhen
·ͱΊ • جૅฤ • ΤϥʔΛτʔετͰදࣔ͢ΔɿonError • ΘΓͷσʔλΛදࣔ͢ΔɿonErrorReturn • ΤϥʔͷछྨͰॲཧΛذ͢ΔɿonErrorResumeNext •
ϦτϥΠ͢Δɿretry • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔɿretryWhen
·ͱΊ • Ԡ༻ฤ • ϦτϥΠˍΩϟογϡɿretry, onErrorReturn • ϦτϥΠˍΩϟογϡˍτʔετɿretry, onErrorReturn, onError
·ͱΊ • ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά • RxJavaCallAdapterFactoryͷ֦ு
Thank you :) Credit: NASA Earth Observatory/NOAA NGDC