【发布时间】:2018-09-10 12:23:45
【问题描述】:
我当前的 Android 应用程序正在使用 Retrofit(2.4.0) 和 RxJava(2.1.16) 来执行我的 Web 服务调用。
我正在使用 Google SignIn 进行用户身份验证。
我希望我的 Retrofit 调用检测 HTTP 401(未经授权)并尝试使用 Google Signin 静默登录 然后重试 Retrofit 调用。
我的改装电话与此类似
@Headers(HEADER_ACCEPT_JSON)
@GET("resources")
Observable<Response<String>> getResources(@Header(HEADER_AUTHORIZATION) @NonNull final String authenticationToken, @QueryMap(encoded = true) @NonNull Map<String, Object> queryMap);
API_SERVICE.getResources(Login.getAuthorizationToken(), id)
.subscribeOn(Schedulers.io())
.subscribe(Network::manageResource, Network::handle));
通过谷歌搜索我可以看到 retry/retryWhen 只会在我的 RxJava 链中发生错误时触发, 但是 HTTP 401 错误不会引发这种情况。
作为 RxJava 的新手,我如何检测我的 HTTP 401 代码和..
一)。执行 Google SignIn 静默登录
b)。静默登录完成 OK,重试我的 API 调用?
更新
我用下面的代码更接近了
@Headers(HEADER_ACCEPT_JSON)
@GET("resources")
Single<Response<String>> getResources(@Header(HEADER_AUTHORIZATION) @NonNull final String authenticationToken, @QueryMap(encoded = true) @NonNull Map<String, Object> queryMap);
API_SERVICE.getResources(Login.getAuthorizationToken(), id)
.subscribeOn(Schedulers.io())
.flatMap(new Function<Response<Article>,
SingleSource<Response<Article>>>() {
@Override
public SingleSource<Response<Article>> apply(final Response<Article> response) {
Log.d(TAG, "apply() called with: response = [" + response + "]");
if (response.isSuccessful()) {
return Single.just(response);
} else {
return Single.error(new RuntimeException());
}
}
})
.retryWhen(errors -> errors.take(1).flatMap(new Function<Throwable, Publisher<?>>() {
@Override
public Publisher<?> apply(final Throwable throwable) {
Log.d(TAG, "apply() called with: throwable = [" + throwable + "]");
Login.loginSilently().subscribe();
return Flowable.just("DELAY").delay(10, TimeUnit.SECONDS);
}
}))
.subscribe(Network::manageResource, Network::handle));
我不喜欢 Flowable.just("DELAY").delay() 调用,即使我现在正在捕获异常并静默登录 OK,但我得到了这个异常
09-10 16:39:29.878 7651-7718/research.android E/Network: handle:
java.util.NoSuchElementException
at io.reactivex.internal.operators.flowable.FlowableSingleSingle$SingleElementSubscriber.onComplete(FlowableSingleSingle.java:116)
at io.reactivex.subscribers.SerializedSubscriber.onComplete(SerializedSubscriber.java:168)
at io.reactivex.internal.operators.flowable.FlowableRepeatWhen$WhenReceiver.onComplete(FlowableRepeatWhen.java:119)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drainLoop(FlowableFlatMap.java:426)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.drain(FlowableFlatMap.java:366)
at io.reactivex.internal.operators.flowable.FlowableFlatMap$InnerSubscriber.onComplete(FlowableFlatMap.java:673)
at io.reactivex.subscribers.SerializedSubscriber.onComplete(SerializedSubscriber.java:168)
at io.reactivex.internal.operators.flowable.FlowableDelay$DelaySubscriber$OnComplete.run(FlowableDelay.java:139)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
09-10 16:39:29.878 7651-7678/research.android D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled
如何在等待静默登录完成时重试?
和
是什么导致了 NoSuchElementException?
【问题讨论】:
标签: android retrofit2 rx-java2