Android 使用rxjava进行改造,以全局方式处理网络异常
我试图在全局级别上处理应用程序中的异常,所以改型会抛出一个错误,我在某个特定类中捕获到它,并使用处理这些错误的逻辑 我有一个接口Android 使用rxjava进行改造,以全局方式处理网络异常,android,retrofit,rx-java,Android,Retrofit,Rx Java,我试图在全局级别上处理应用程序中的异常,所以改型会抛出一个错误,我在某个特定类中捕获到它,并使用处理这些错误的逻辑 我有一个接口 @POST("/token") AuthToken refreshToken(@Field("grant_type") String grantType, @Field("refresh_token") String refreshToken); 和可观察到的 /** * Refreshes auth token * * @param refreshToken
@POST("/token")
AuthToken refreshToken(@Field("grant_type") String grantType, @Field("refresh_token") String refreshToken);
和可观察到的
/**
* Refreshes auth token
*
* @param refreshToken
* @return
*/
public Observable<AuthToken> refreshToken(String refreshToken) {
return Observable.create((Subscriber<? super AuthToken> subscriber) -> {
try {
subscriber.onNext(apiManager.refreshToken(REFRESH_TOKEN, refreshToken));
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}).subscribeOn(Schedulers.io());
}
然后在我的主要活动中,我订阅该行为主题并解析错误
SomeApi.getErrorEvent().subscribe(
(e) -> {
//parse the error
}
);
但是我不能重复对抛出错误的可观察对象的调用。您需要使用操作符,更好地解释为: 下一步将继续( )方法返回一个反映源可观察对象行为的可观察对象,除非该可观察对象调用onError( ) 在这种情况下,与其将该错误传播给订阅者,不如继续下一步( ) 而是开始镜像第二个可观察到的备份 在你的情况下,我会这样说:
getCurrentUser = userApi.getCurrentUser()
.onErrorResumeNext(refreshTokenAndRetry(userApi.getCurrentUser()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...)
其中:
private <T> Func1<Throwable,? extends Observable<? extends T>> refreshTokenAndRetry(final Observable<T> toBeResumed) {
return new Func1<Throwable, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(Throwable throwable) {
// Here check if the error thrown really is a 401
if (isHttp401Error(throwable)) {
return refreshToken().flatMap(new Func1<AuthToken, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(AuthToken token) {
return toBeResumed;
}
});
}
// re-throw this error because it's not recoverable from here
return Observable.error(throwable);
}
};
}
private Func1@Override
公共可观察消息(字符串accountId,int messageType){
返回mMessageService.getLikeMessages(messageType)
.onErrorResumeNext(mTokenTrick)。
refreshTokenAndRetry(mMessageService.getLikeMessages(messageType));
}
你能展示一下你现在如何将refreshToken()
observable与其他调用联系起来吗?在上面的回答中,我想使用defer()
操作符来避免用旧的observable重新尝试请求。代码:onErrorResumeNext(refreshTokenAndRetry(observable.defer(()->userApi.getCurrentUser()))
。希望对某人有用:)@blizzard谢谢你的评论。事实证明,对我来说,你的建议非常重要
getCurrentUser = userApi.getCurrentUser()
.onErrorResumeNext(refreshTokenAndRetry(userApi.getCurrentUser()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(...)
private <T> Func1<Throwable,? extends Observable<? extends T>> refreshTokenAndRetry(final Observable<T> toBeResumed) {
return new Func1<Throwable, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(Throwable throwable) {
// Here check if the error thrown really is a 401
if (isHttp401Error(throwable)) {
return refreshToken().flatMap(new Func1<AuthToken, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(AuthToken token) {
return toBeResumed;
}
});
}
// re-throw this error because it's not recoverable from here
return Observable.error(throwable);
}
};
}
@Override
public Observable<List<MessageEntity>> messages(String accountId, int messageType) {
return mMessageService.getLikeMessages(messageType)
.onErrorResumeNext(mTokenTrick.
refreshTokenAndRetry(mMessageService.getLikeMessages(messageType)));
}