我正在使用rx-android改装2
我有相当复杂的重试逻辑,部分工作.我切断了不相关的代码来简化它.这里是:
public class RetryWithDelay implements Func1, Observable>>, Constants { @Override public Observable> call(Observable extends Throwable> attempts) { return attempts.flatMap(new Func1 >() { @Override public Observable> call(Throwable throwable) { int statusCode = 500; if (throwable instanceof HttpException) { HttpException httpException = (HttpException) throwable; statusCode = httpException.code(); } boolean shouldRetry = shouldRetry(); if (shouldRetry && statusCode == 401 && requiresAuthorization) { LoginProvider provider = AppUtils.getExternalProvider(context); switch (provider) { case GOOGLE: return reauthorizeGoogleProvider(); case FACEBOOK: return reauthorizeFacebookProvider(); default: return reauthorizeApiProvider(); } } else if (shouldRetry) { return Observable.timer(Configuration.REQUEST_RETRY_DELAY_IN_SECONDS, TimeUnit.SECONDS); } else { return Observable.error(throwable); } } }); }
我有网络调用observable,它抛出401.然后触发重试逻辑.电话看起来像
observable .subscribeOn(Schedulers.newThread()) .retryWhen(new RetryWithDelay(getActivity())) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber() { //code removed for simplicity });
当我得到401 RetryWithDelay开关触发三种方法之一.当用户在我的api中本地登录时,它工作正常,调用:
private Observable> reauthorizeApiProvider() { return retrofitService.loginWithRefreshToken(data).flatMap(new Func1>() { @Override public Observable> call(User user) { app.setUserInfo(UserInfo.fromUser(user)); AppUtils.saveUserData(context, user); return Observable.timer(0, TimeUnit.MICROSECONDS); } }); }
但对于Facebook或谷歌最终有神秘的例外:java.io.InterruptedIOException: thread interrupted
.这就是我为谷歌做的方式 - 对于Facebook也一样.
private Observable> reauthorizeGoogleProvider() { return retrofitService.loginWithExternalProvider(LoginProvider.GOOGLE, externalAccessToken).flatMap(new Func1>() { @Override public Observable> call(User user) { //some irrelevant logic return Observable.timer(0, TimeUnit.MICROSECONDS); } }); }
我传递给改造方法的参数没有任何问题.登录时成功使用具有相同参数的此方法,而不是重试逻辑的一部分.
这是完整的堆栈跟踪:
java.io.InterruptedIOException: thread interrupted 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.Timeout.throwIfReached(Timeout.java:145) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.Okio$1.write(Okio.java:77) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.AsyncTimeout$1.write(AsyncTimeout.java:155) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.RealBufferedSink.flush(RealBufferedSink.java:221) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:141) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpTransport.finishRequest(HttpTransport.java:52) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:92) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:891) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:749) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.getResponse(Call.java:268) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.myapp.android.dagger.ApiModule$1.intercept(ApiModule.java:81) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:221) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.execute(Call.java:79) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.OkHttpCall.execute(OkHttpCall.java:116) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:111) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:88) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:231) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:140) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$3$1.onNext(OnSubscribeRedo.java:307) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$3$1.onNext(OnSubscribeRedo.java:289) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.subjects.SubjectSubscriptionManager$SubjectObserver.emitNext(SubjectSubscriptionManager.java:254) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.subjects.BehaviorSubject.onNext(BehaviorSubject.java:160) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$2$1.onError(OnSubscribeRedo.java:242) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorSubscribeOn$1$1$1.onError(OperatorSubscribeOn.java:71) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:239) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:774) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:532) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:521) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:808) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$ThrowObservable$1.call(Observable.java:9600) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$ThrowObservable$1.call(Observable.java:9590) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:231) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:140) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:113) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:88) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.lang.Thread.run(Thread.java:818)
请指教
编辑:调查显示它以某种方式连接到http方法.loginWithRefreshToken
是POST
和loginWithExternalProvider
是GET
.更改ti POST时工作.但那太愚蠢了.需要真正的解决方