我是RxJava框架的新手。我的系统使用令牌身份验证,当我想从http请求获得任何响应时,我需要刷新我的身份验证令牌,因为到期时间。
但是在从一个observable调用subscribe方法到另一个可观察的
之后我遇到了一个问题主类(第一个可观察的)
service.getPosts(offset,limit, PreferencesUtils.getAccessTokenKey())
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(response -> {
if (!response.isSuccessful()) throw new RuntimeException();
})
.subscribe(
feeds -> mView.showNewsFeedItems(feeds.body()),
error -> {
Helper.refreshToken();
service.getPosts(offset,limit,PreferencesUtils.getAccessTokenKey());
}
);
我的回复不成功,我需要调用refreshToken()
我可以刷新令牌并将其保存到PreferencesUtils
助手类(第二个可观察的)
service.refreshToken(PreferencesUtils.getAccessTokenKey(), PreferencesUtils.getRefreshTokenKey())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(Schedulers.newThread())
.subscribe(
// doesnt proceed this part of code
response -> {
PreferencesUtils.saveAccessToken(response.body().getAccessToken());
PreferencesUtils.saveRefreshToken(response.body().getRefreshToken());
},
error -> Log.d(TAG, "refresh token exception: " + `error.getMessage())`
//
);
当我使用调试器时,来自Helper类的第二个observable不能正常工作它不想继续这项服务并且在订阅时立即完成而没有任何错误(当然它正在等待完成主线程的所有操作)。由于订阅方法没有继续(没有将访问令牌保存到首选项),我无法执行service.getPosts()
功能。
请帮忙!我将非常感激!
答案 0 :(得分:1)
不要像这样拆分观察者链,而是使用spdx
运算符来响应失败的令牌。
retryWhen()
Observable.just(Boolean.TRUE)
.flatMap( ignored -> service
.getPosts(offset,limit,
PreferencesUtils.getAccessTokenKey()) )
.subscribeOn(Schedulers.computation())
.doOnNext(response -> {
if (!response.isSuccessful()) throw new TokenException();
})
.retryWhen( error -> error.flatMap( f ->
{
if ( f instanceof TokenException ) {
return service.refreshToken(PreferencesUtils.getAccessTokenKey(), PreferencesUtils.getRefreshTokenKey())
.doOnNext( response -> {
PreferencesUtils.saveAccessToken(response.body().getAccessToken());
PreferencesUtils.saveRefreshToken(response.body().getRefreshToken());
});
}
return Observable.error(f);
})
)
.observeOn(AndroidSchedulers.mainThread())
.subscribe( /* do stuff */ );
运算符采用一个observable来获取上游引发的任何异常。如果异常是retryWhen()
,它将尝试通过调用TokenException
返回的observable来刷新令牌,然后将结果保存到您的首选项中。
编辑:使用可以重新订阅而没有问题的observable启动观察者链。必须刷新访问令牌时,将使用新令牌调用refreshToken()
。