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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Yuya Kaido
March 10, 2017
Programming
8.4k
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
240
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
110
retty-tech-cafe-8
yuyakaido
0
210
mti-eureka-tech-beer
yuyakaido
0
510
potatotips-33
yuyakaido
2
690
Other Decks in Programming
See All in Programming
パズルゲームの作り方 / how to make puzzle games
kaityo256
PRO
2
250
速習iPhone Duo対応
yuukiw00w
2
910
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
320
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
560
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3k
巨大モノリシックアプリ モダン化大作戦
ktcryomm
1
1.2k
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
19
19k
GitHubハンズオン講座 — 実務レベルのチーム開発のフローを身につけよう
junhat6
0
110
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
9.2k
JRuby: Past, Present, and Future
headius
0
210
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
フロントエンドUIフレームワークのこれまでとこれから
ssssota
5
3.1k
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Deep Space Network (abreviated)
tonyrice
0
350
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
Thoughts on Productivity
jonyablonski
76
5.4k
The browser strikes back
jonoalderson
0
1.7k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
340
Leo the Paperboy
mayatellez
10
2.3k
Practical Orchestrator
shlominoach
192
12k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
1k
Building Better People: How to give real-time feedback that sticks.
wjessup
370
20k
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