droidkaigi-2017

 droidkaigi-2017

836437265cbba12ee1b24bbb359a6c15?s=128

Yuya Kaido

March 10, 2017
Tweet

Transcript

  1. Error Handling in RxJava DroidKaigi 2017 yuyakaido

  2. ࣗݾ঺հ • ւ౻༏໻ʢ͔͍Ͳ͏Ώ͏΍ʣ • AndroidΤϯδχΞ yuyakaido

  3. ձࣾ঺հ • גࣜձࣾΤ΢ϨΧ • ࣗࣾΞϓϦͷاըɾ։ൃɾӡӦ • ΦϯϥΠϯσʔςΟϯά • Χοϓϧίϛϡχέʔγϣϯ

  4. ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ

  5. ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ •

    OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢
  6. ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ •

    OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢
  7. ຊηογϣϯͰ͓఻͍͑ͨ͜͠ͱ • RxJavaͬͯOperator͕ଟͯ͘೉ͦ͠͏ • ΤϥʔϋϯυϦϯά༻ͷOperator͸ଟ͋͘Γ·ͤΜ • Ϣʔεέʔε͔Βߟ͑ͯΈΔͱ͍͍͔΋ • RxJavaΛ࢖Θͣʹ࣮૷͢Δ৔߹ͱൺֱͨ͠ϝϦοτ͸ʁ •

    OperatorΛ૊Έ߹ΘͤΔ͜ͱͰॊೈͳΤϥʔϋϯυϦ ϯάΛ࣮૷͢Δ͜ͱ͕ग़དྷ·͢
  8. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  9. ໨࣍ɿجຊฤ • αϯϓϧɿެࣜΞϓϦͷContributorΛදࣔ͢Δ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ •

    ϦτϥΠ͢Δ • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  10. ໨࣍ɿԠ༻ฤ • جຊฤͰొ৔ͨ͠ΤϥʔϋϯυϦϯάΛ૊Έ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ •

    Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍৔߹͸τʔετΛදࣔ͢Δ
  11. ໨࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά

  12. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  13. RxJavaͷ͓͞Β͍ • Reactive Extension for Java • ඇಉظετϦʔϜ • σʔλϑϩʔΛఆٛͯ͠ɺมߋΛ఻ൖͤ͞Δ

    ग़యɿhttp://reactivex.io/
  14. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  15. RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • Τϥʔൃੜ࣌ʹϦΧόϦʔΛߦ͏ • onError, onErrorReturn, onErrorResumeNext •

    Retry • Τϥʔൃੜ࣌ʹresubscribe͢Δ • retry, retryWhen
  16. Catch • onError • onErrorReturn • onErrorResumeNext

  17. Catch • onError • onErrorReturn • onErrorResumeNext

  18. onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ

  19. 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);
 }
 });
  20. 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);
 }
 });
  21. 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);
 }
 });
  22. 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);
 }
 });
  23. 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);
 }
 });
  24. 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
  25. 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
  26. 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
  27. 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
  28. onError • Τϥʔ͕Τϛοτ͞Εͨͱ͖ʹݺͼग़͞ΕΔ • Τϥʔ಺༰͕Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ࢖ͬͯΤϥʔϋϯυϦϯάΛߦ͏

  29. Catch • onError • onErrorReturn • onErrorResumeNext

  30. onErrorReturn • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹ୅ΘΓͷσʔλΛฦ͢ ग़యɿhttp://reactivex.io/

  31. onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1<Throwable, String>() {
 @Override
 public

    String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());
  32. onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1<Throwable, String>() {
 @Override
 public

    String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());
  33. 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ʯΛΤϛοτ͢Δ
  34. 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͔ΒྲྀΕ͖ͯͨΠϕϯτΛϩάʹදࣔ͢Δ
  35. onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1<Throwable, String>() {
 @Override
 public

    String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());
  36. onErrorReturn Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .onErrorReturn(new Func1<Throwable, String>() {
 @Override
 public

    String call(Throwable throwable) {
 return "onErrorReturn";
 }
 })
 .subscribe(new LoggingSubscriber());
  37. 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( )
  38. 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( )
  39. 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( )
  40. 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( )
  41. 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( )
  42. 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( )
  43. 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( )
  44. 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( )
  45. onErrorReturn • Τϥʔ͕ൃੜͨ͠৔߹ʹ୅ΘΓͷσʔλΛฦ͢ • Τϥʔ಺༰͸Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ΋ͱʹ୅ΘΓͷσʔλΛฦ͢ • ΋ͱͷObservable͸Complete͢Δ

  46. Catch • onError • onErrorReturn • onErrorResumeNext

  47. onErrorResumeNext • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹ୅ΘΓͷObservableΛ ฦ͢ ग़యɿhttp://reactivex.io/

  48. 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());
  49. 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());
  50. 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( )
  51. 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( )
  52. 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( )
  53. 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( )
  54. 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( )
  55. 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( )
  56. 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( )
  57. 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( )
  58. onErrorResumeNext • Τϥʔ͕ൃੜͨ͠৔߹ʹ୅ΘΓͷObservableΛฦ͢ • Τϥʔ಺༰͸Throwableͱͯ͠౉͞ΕΔ • ThrowableΛ΋ͱʹ୅ΘΓͷObservableΛฦ͢ • ΋ͱͷObservable͸Complete͢Δ

  59. Retry • retry • retryWhen

  60. Retry • retry • retryWhen

  61. retry • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹresubscribe͢Δ ग़యɿhttp://reactivex.io/

  62. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber());

  63. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber());

  64. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); retry(1)

  65. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); retry(1)

  66. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

  67. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

  68. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

  69. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

    subscribe
  70. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext retry(1)

    subscribe
  71. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava:

    onNext retry(1) subscribe
  72. retry Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retry(1)
 .subscribe(new LoggingSubscriber()); D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava:

    onNext retry(1) subscribe
  73. 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
  74. retry • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹresubscribe͢Δ • Τϥʔ͕Τϛοτ͞Εͨ৔߹ʹଈ࠲ʹresubscribe͢Δ • Ҿ਺Ͱճ਺Λࢦఆ͢Δ͜ͱ͕ग़དྷΔ

  75. Retry • retry • retryWhen

  76. retryWhen • resubscribe͢Δ৚݅Λࡉ੍͔͘ޚͰ͖Δ • resubscribe͢ΔͨΊͷτϦΨʔͱͳΔObservableΛฦ͢ • τϦΨʔʹNextΛΤϛοτ͢Δͱresubscribe • τϦΨʔʹCompleteΛΤϛοτ͢ΔͱComplete •

    τϦΨʔʹErrorΛΤϛοτ͢ΔͱError ग़యɿhttp://reactivex.io/
  77. retryWhen • ϚʔϒϧμΠΞάϥϜͰߟ͑ͯΈΔ ग़యɿhttp://reactivex.io/

  78. retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

  79. retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

  80. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

  81. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

  82. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  83. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  84. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  85. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  86. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  87. Τϥʔͷ··ऴྃ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.flatMap(Observable::error)
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  88. Τϥʔͷ··ऴྃ͢Δ 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 ( )
  89. retryWhen • Τϥʔͷ··ऴྃ͢Δ • Τϥʔ࣌ʹComplete͢Δ • গ࣌ؒ͠Λ͓͍ͯϦτϥΠ͢Δ

  90. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

  91. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

  92. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  93. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  94. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  95. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    retryWhen ( )
  96. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  97. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  98. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  99. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext retryWhen ( )
  100. Τϥʔ࣌ʹComplete͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable ->
 observable.first().ignoreElements()
 )
 .subscribe(new LoggingSubscriber());

    D/ErrorHandlingInRxJava: onNext D/ErrorHandlingInRxJava: onCompleted retryWhen ( )
  101. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber());
  102. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber());
  103. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )
  104. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )
  105. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )
  106. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ Observable.create(new NextThenError(), Emitter.BackpressureMode.NONE)
 .retryWhen(observable -> 
 observable.first().flatMap(throwable -> 


    Observable.timer(3, TimeUnit.SECONDS)
 )
 )
 .subscribe(new LoggingSubscriber()); retryWhen ( )
  107. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
  108. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
  109. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
  110. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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 ( )
  111. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  112. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  113. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  114. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  115. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  116. ࣌ؒΛ͓͍ͯϦτϥΠ͢Δ 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
  117. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  118. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  119. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  120. ΤϥʔΛτʔετͰදࣔ͢Δ • Ϣʔεέʔε • ΤϥʔϝοηʔδΛදࣔ͢Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ •

    onError
  121. ΤϥʔΛτʔετͰදࣔ͢Δ

  122. ΤϥʔΛτʔετͰදࣔ͢Δ 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
 }
 });
  123. ΤϥʔΛτʔετͰදࣔ͢Δ 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
 }
 });
  124. ΤϥʔΛτʔετͰදࣔ͢Δ 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
 }
 });
  125. ΤϥʔΛτʔετͰදࣔ͢Δ 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
 }
 });
  126. ΤϥʔΛτʔετͰදࣔ͢Δ 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
 }
 });
  127. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  128. ୅ΘΓͷσʔλΛදࣔ͢Δ • Ϣʔεέʔε • αʔόʔ͔Βσʔλ͕औಘͰ͖ͳ͔ͬͨ৔߹ʹɺΩϟο γϡ͍ͯ͠ΔσʔλΛදࣔ͢Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ

    • ୅ΘΓʹΩϟογϡ͔ΒऔΓग़ͨ͠σʔλΛྲྀ͢ • onErrorReturn
  129. ୅ΘΓͷσʔλΛදࣔ͢Δ

  130. ୅ΘΓͷσʔλΛදࣔ͢Δ 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͔Βऔಘ
 }
 });
  131. ୅ΘΓͷσʔλΛදࣔ͢Δ 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͔Βऔಘ
 }
 });
  132. ୅ΘΓͷσʔλΛදࣔ͢Δ 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͔Βऔಘ
 }
 });
  133. ୅ΘΓͷσʔλΛදࣔ͢Δ 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͔Βऔಘ
 }
 });
  134. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  135. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • Ϣʔεέʔε • αʔόʔ͕ฦͨ͠ΤϥʔίʔυʹΑͬͯॲཧΛ෼ذ͢ Δ • ࣮૷ํ਑ • ObservableʹྲྀΕͨΤϥʔΛΩϟον͢Δ

    • ΤϥʔͷछྨΛ΋ͱʹॲཧΛ෼ذ͢Δ • onErrorResumeNext
  136. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  137. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  138. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  139. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  140. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  141. ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ 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);
 }
 }
 );
  142. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  143. ϦτϥΠ͢Δ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠৔߹ʹϦτϥΠ͢Δ • ࣮૷ํ਑ • ObservableʹΤϥʔ͕ྲྀΕͨ৔߹ʹresubscribe͢Δ •

    retry
  144. ϦτϥΠ͢Δ client.getDroidKaigiContributors()
 .retry(3);

  145. جຊฤ • ΤϥʔΛτʔετͰදࣔ͢Δ • ୅ΘΓͷσʔλΛදࣔ͢Δ • ΤϥʔͷछྨͰॲཧΛ෼ذ͢Δ • ϦτϥΠ͢Δ •

    ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ
  146. ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ • Ϣʔεέʔε • αʔόʔ͕ΤϥʔΛฦͨ͠৔߹ʹSnackbarΛදࣔ͠ ͯɺϦτϥΠ͢Δ͔ΛਘͶΔ • ࣮૷ํ਑ • ObservableʹΤϥʔ͕ྲྀΕͨΒSnackbarΛදࣔ͢Δ

    • Ϣʔβʔ͕ϦτϥΠΛԡͨ͠৔߹ʹresubscribe͢Δ
  147. ϦτϥΠ͢Δ͔Ͳ͏͔ΛϢʔβʔʹਘͶΔ

  148. ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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))
 )
  149. ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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))
 )
  150. ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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))
 )
  151. ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔ .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))
 )
  152. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  153. Ԡ༻ฤ • جຊฤͰొ৔ͨ͠ΤϥʔϋϯυϦϯάΛ૊Έ߹ΘͤΔ • Ϣʔεέʔε1 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ •

    Ϣʔεέʔε2 • ϦτϥΠΛ3ճߦ͏ • μϝͳΒΩϟογϡΛදࣔ͢Δ • Ωϟογϡ͕ͳ͍৔߹͸τʔετΛදࣔ͢Δ
  154. Ϣʔεέʔε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͔Βऔಘ
 }
 });
  155. Ϣʔεέʔε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͔Βऔಘ
 }
 });
  156. Ϣʔεέʔε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͔Βऔಘ
 }
 });
  157. Ϣʔεέʔε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͔Βऔಘ
 }
 });
  158. Ϣʔεέʔε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͔Βऔಘ
 }
 });
  159. Ϣʔεέʔε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);
 }
 }
 );
  160. Ϣʔεέʔε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);
 }
 }
 );
  161. Ϣʔεέʔε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);
 }
 }
 );
  162. Ϣʔεέʔε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);
 }
 }
 );
  163. Ϣʔεέʔε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);
 }
 }
 );
  164. Ϣʔεέʔε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);
 }
 }
 );
  165. Ϣʔεέʔε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);
 }
 }
 );
  166. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  167. ໨࣍ɿ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά

  168. 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);
 }
 }
 );
  169. RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹ࢓ࠐΉʹ͸ • ίϐϖ • Ϋϥεʹ੾Γग़ͯ͠ɺͦΕΛશAPIʹ࢓ࠐΉ

  170. RetrofitͷΤϥʔϋϯυϦϯά • ઌͷΤϥʔॲཧΛશAPIʹ࢓ࠐΉʹ͸ • ίϐϖ • Ϋϥεʹ੾Γग़ͯ͠ɺͦΕΛશAPIʹ࢓ࠐΉ • RxJavaCallAdapterFactoryͷ֦ு

  171. 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<>());
 }
 }
 }
  172. 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<>());
 }
 }
 }
  173. 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<>());
 }
 }
  174. 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<>());
 }
 }
  175. RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder()
 .baseUrl(BuildConfig.API_ENDPOINT)
 .client(okHttpClient)
 .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application))
 .addConverterFactory(GsonConverterFactory.create())
 .build()

  176. RetrofitͷΤϥʔϋϯυϦϯά Retrofit.Builder()
 .baseUrl(BuildConfig.API_ENDPOINT)
 .client(okHttpClient)
 .addCallAdapterFactory(RxJavaErrorHandlingCallAdapterFactory.create(application))
 .addConverterFactory(GsonConverterFactory.create())
 .build()

  177. ໨࣍ • RxJavaͷ͓͞Β͍ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • جຊฤ • Ԡ༻ฤ •

    ࣮ફฤ • ·ͱΊ
  178. ·ͱΊ • RxJavaʹ͓͚ΔΤϥʔϋϯυϦϯά • Catch • onError, onErrorReturn, onErrorResumeNext •

    Retry • retry, retryWhen
  179. ·ͱΊ • جૅฤ • ΤϥʔΛτʔετͰදࣔ͢ΔɿonError • ୅ΘΓͷσʔλΛදࣔ͢ΔɿonErrorReturn • ΤϥʔͷछྨͰॲཧΛ෼ذ͢ΔɿonErrorResumeNext •

    ϦτϥΠ͢Δɿretry • ϦτϥΠ͢Δ͔ΛϢʔβʔʹਘͶΔɿretryWhen
  180. ·ͱΊ • Ԡ༻ฤ • ϦτϥΠˍΩϟογϡɿretry, onErrorReturn • ϦτϥΠˍΩϟογϡˍτʔετɿretry, onErrorReturn, onError

  181. ·ͱΊ • ࣮ફฤ • RetrofitͷΤϥʔϋϯυϦϯά • RxJavaCallAdapterFactoryͷ֦ு

  182. Thank you :) Credit: NASA Earth Observatory/NOAA NGDC