diff --git a/README.md b/README.md index 3818a59..fc44fcc 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ for(String login : Data.githubList) { service.getUser(login) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) + .retryWhen(new RetryWithIncreasingDelay(3,3000,false)) .subscribe(new Subscriber() { @Override public final void onCompleted() { @@ -119,6 +120,10 @@ GithubService Interface has the getUser method which returns an Observable. We a .observeOn(AndroidSchedulers.mainThread()) ``` These two lines specify that the REST call will be made in a new thread (YES!). And when the call response returns, it call the onNext, onError, and onComplete methods on the mainThread. The reason we need to call them on the mainThread is that only the mainThread can update the UI. If you have data that do not need to be displayed immediately, you would not need to observe on main thread. The difference between observeOn and subscribeOn is best explained in this [stackoverflow](http://stackoverflow.com/questions/20451939/observeon-and-subscribeon-where-the-work-is-being-done). +```java +.retryWhen(new RetryWithIncreasingDelay(3,3000,false)) +``` +This line returns an Observable that emits the same values as the source observable with the exception of an onError. ```java new Subscriber() { diff --git a/app/src/main/java/app/activity/MainActivity.java b/app/src/main/java/app/activity/MainActivity.java index ee28c63..ea226ae 100644 --- a/app/src/main/java/app/activity/MainActivity.java +++ b/app/src/main/java/app/activity/MainActivity.java @@ -8,12 +8,15 @@ import android.view.Menu; import android.view.View; import android.widget.Button; + +import com.example.githubdemo.app.R; + import app.Data; import app.adapter.CardAdapter; import app.model.Github; +import app.rx.RetryWithIncreasingDelay; import app.service.GithubService; import app.service.ServiceFactory; -import com.example.githubdemo.app.R; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; @@ -53,6 +56,7 @@ public void onClick(View v) { service.getUser(login) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) + .retryWhen(new RetryWithIncreasingDelay(3,3000,false)) .subscribe(new Subscriber() { @Override public final void onCompleted() { diff --git a/app/src/main/java/app/rx/RetryWithIncreasingDelay.java b/app/src/main/java/app/rx/RetryWithIncreasingDelay.java new file mode 100644 index 0000000..d4c2977 --- /dev/null +++ b/app/src/main/java/app/rx/RetryWithIncreasingDelay.java @@ -0,0 +1,45 @@ +package app.rx; + +import java.util.concurrent.TimeUnit; + +import rx.Observable; +import rx.functions.Func1; + +/** + * Created by doomtrooper on 22/10/15. + */ +public class RetryWithIncreasingDelay implements + Func1, Observable> { + + private final int maxRetries; + private final int retryDelayMillis; + private final boolean incRetryDelay; + private int retryCount; + + public RetryWithIncreasingDelay(int maxRetries, int retryDelayMillis, boolean incRetryDelay) { + this.maxRetries = maxRetries; + this.retryDelayMillis = retryDelayMillis; + this.incRetryDelay = incRetryDelay; + this.retryCount = 0; + } + + + @Override + public Observable call(Observable observable) { + return observable.flatMap(new Func1>() { + @Override + public Observable call(Throwable throwable) { + if (++retryCount < maxRetries) { + // When this Observable calls onNext, the original + // Observable will be retried (i.e. re-subscribed). + return incRetryDelay?Observable.timer(retryDelayMillis*retryCount, + TimeUnit.MILLISECONDS):Observable.timer(retryDelayMillis, + TimeUnit.MILLISECONDS); + } + + // Max retries hit. Just pass the error along. + return Observable.error(throwable); + } + }); + } +}