Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
droidkaigi-2017
Search
Yuya Kaido
March 10, 2017
Programming
8.5k
11
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
droidkaigi-2017
Yuya Kaido
March 10, 2017
More Decks by Yuya Kaido
See All by Yuya Kaido
droidkaigi-2019
yuyakaido
7
4.9k
matching-dev-meetup-1
yuyakaido
1
250
minami-aoyama-night-6
yuyakaido
1
1.3k
eureka-meetup-10
yuyakaido
0
860
droidkaigi-2018
yuyakaido
4
6.3k
navitime-eureka-1
yuyakaido
0
120
retty-tech-cafe-8
yuyakaido
0
210
mti-eureka-tech-beer
yuyakaido
0
520
potatotips-33
yuyakaido
2
690
Other Decks in Programming
See All in Programming
プロジェクトコードをキレイキレイしよう!暗黙的な参照を読み解く静的解析
ostk0069
0
210
小さなアプリを作って公開するまで
onozaty
0
150
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
240
Distance field of Julia set
kinakomoti321
0
310
Long Living Tokens, Die, Die, Die! (or: The One Ring is Banned in Modern)
sylph01
0
420
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
310
flutter_test のその先へ — Flutter アプリの LLM 機能に「評価」という品質保証を
kosukesaigusa
0
200
[JA] Domain Modeling with Vanilla Rails: 「操作」から再考するRailsの設計論
yasaichi
4
1.8k
Modernizing iOS Apps
seyfoyun
0
150
まずはコードより業務と向き合う:テーブル解体のためにPdMを呼んだ話
sakawe_ee
0
190
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
210
AIで開発が速くなった先で、開発チームは何を目指すか
shihochan
1
2k
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.2k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
560
Designing Experiences People Love
moore
143
24k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Design in an AI World
tapps
1
390
エンジニアに許された特別な時間の終わり
watany
109
250k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
70
68k
Navigating Weather and Climate Data
rabernat
0
590
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
650
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.9k
Agile that works and the tools we love
rasmusluckow
331
22k
Site-Speed That Sticks
csswizardry
13
1.6k
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