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.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
850
droidkaigi-2018
yuyakaido
4
6.2k
navitime-eureka-1
yuyakaido
0
110
retty-tech-cafe-8
yuyakaido
0
210
mti-eureka-tech-beer
yuyakaido
0
510
potatotips-33
yuyakaido
2
680
Other Decks in Programming
See All in Programming
DroidKaigi 2026 「個人開発という実験場: Android エンジニアが手にする4つの自由」
slashnephy
0
230
What We Talk About When We Talk About XP
m_seki
2
620
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
210
Intent as Code
shoppingjaws
6
1k
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
6
1.9k
Security issues being discussed on Web Platforms
petamoriken
0
940
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
150
一人だけ、Kiroが静止する日
hideg
0
110
AIエージェント時代のコードレビューを設計する
nogu66
6
2.7k
新人はどこまで自力でやり、どこからAIに頼るべきか/エンジニア育成に向き合う_先輩たちの悩みと知見共有会
toppan_digital_dev
1
620
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
170
そのリトライ、死んだコネクションを使い回していませんか ── GoのHTTPクライアントとHTTP/2を実プロダクト障害から学び直す
myus4a
0
140
Featured
See All Featured
Git: the NoSQL Database
bkeepers
PRO
432
67k
ラッコキーワード サービス紹介資料
rakko
1
4.9M
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
690
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
36k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
450
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
A better future with KSS
kneath
240
18k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
First, design no harm
axbom
PRO
2
1.3k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
520
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