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
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
Agents on Rails - Rails at Scale 2026
irinanazarova
0
340
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
130
CodeRabbitの効果検証と過ごしてみた3ヶ月
armondando
0
150
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
350
自サークルのIdPからログアウトできるようになるまで
taiseiue
0
110
contenteditable と日本語入力に向き合う
colorful12
0
140
phperだってパンチカードでコーディングしたい
o0h
PRO
0
210
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
120
残高管理から台帳サービスへの進化
artoy
0
150
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
14
6.7k
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
150
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
550
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1369
210k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
580
The Mindset for Success: Future Career Progression
greggifford
PRO
0
530
Paper Plane (Part 1)
katiecoart
PRO
2
11k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
290
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
320
Un-Boring Meetings
codingconduct
0
440
Statistics for Hackers
jakevdp
799
230k
Design in an AI World
tapps
1
350
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