我想在改造中为api调用创建一个包装器,这样我就可以在常见位置显示ProgressDialog并处理常见的响应 .
我通过创建这样的包装来实现这一目标
public static <T> Observable<T> callApiWrapper(final Context context,
final boolean shouldShowProgress,
final String message,
final Observable<T> source) {
final ProgressDialog progressDialog = new ProgressDialog(context);
if (shouldShowProgress) {
if (!TextUtils.isEmpty(message))
progressDialog.setMessage(message);
else
progressDialog.setMessage(context.getString(R.string.please_wait));
}
return source.lift(new Observable.Operator<T, T>() {
@Override
public Subscriber<? super T> call(final Subscriber<? super T> child) {
return new Subscriber<T>() {
@Override
public void onStart() {
super.onStart();
if (shouldShowProgress) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
progressDialog.show();
}
});
}
child.onStart();
}
@Override
public void onCompleted() {
if (shouldShowProgress && progressDialog.isShowing())
progressDialog.dismiss();
child.onCompleted();
}
@Override
public void onError(Throwable e) {
if (shouldShowProgress && progressDialog.isShowing())
progressDialog.dismiss();
child.onError(e);
}
@Override
public void onNext(T t) {
/*
Handle Invalid API response
*/
if (((BaseResponse) t).getStatus() == RestParams.Codes.INVALID_API_KEY) {
mCommonDataModel.setApiKey("");
getCommonApiService().getApiKey()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ResponseBody>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(ResponseBody responseBody) {
try {
String response = responseBody.string();
JSONObject jsonObject = new JSONObject(response);
String key = jsonObject.optString("KEY");
if (!TextUtils.isEmpty(key))
mCommonDataModel.setApiKey(key);
callApiWrapper(context, shouldShowProgress,
message, source)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
if (shouldShowProgress && progressDialog.isShowing())
progressDialog.dismiss();
child.onNext(t);
}
}
};
}
});
}
在上面的代码中,我检查如果我得到像Invalid API KEY这样的特定状态代码,那么我调用API来获取新的API密钥,而不是直接将状态提供给原始订阅者 .
一旦我成功获得新的API密钥,我会递归调用包装器并尝试将响应提供给原始订阅者 . 但问题是原始订阅者没有得到 onNext
回调
我在这里错过了什么?有没有其他方法可以实现我想要做的事情?
2 回答
您需要添加一些重试逻辑,以防您遇到无效的密钥失败,例如
为了添加副作用,即在开始订阅时启用进度条,在完成类似的操作时将其解除
最后,我设法创建了一个包装器,在无效密钥API响应的情况下为我处理常见的Progressbar和重试逻辑 . 在许多情况下,这种包装器可能很有用 . 感谢@JohnWowUs的回答,这有助于我理解并实现这个包装器 .
这是工作代码
&使用它与正常相同: