gpt4 book ai didi

android - Retrofit RxAndroid 为 api 调用制作包装器

转载 作者:搜寻专家 更新时间:2023-11-01 07:45:42 25 4
gpt4 key购买 nike

我想在改造中为 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);
}

}
};
}
});

}

在上面的代码中,我检查是否获得了特定的状态代码,如无效的 API key ,然后我调用 API 来获取新的 API key ,而不是直接将状态提供给原始订阅者。

一旦我成功获得新的 API key ,我就会递归调用包装器并尝试将响应提供给原始订阅者。但问题是原始订阅者没有得到 onNext 回调

我在这里错过了什么?有没有其他方法可以实现我想要做的事情?

最佳答案

您需要添加一些重试逻辑,以防出现无效 key 故障,例如

source.flatMap(
t ->
{
if (((BaseResponse) t).getStatus() == RestParams.Codes.INVALID_API_KEY) {
return Observable.error(new InvalidKeyException("The key is not valid"));
}
else {
return Observable.just(t);
}
}
)
.retryWhen(
errors ->
errors.flatMap(error -> {

if (error instanceof InvalidKeyException()) {
return getCommonApiService().getApiKey()
.flatMap(
responseBody -> {
String response = responseBody.string();
JSONObject jsonObject = new JSONObject(response);
String key = jsonObject.optString("KEY");

if (TextUtils.isEmpty(key))
return Observable.error();
else {
return Observable.just(key);
}})
.doOnNext( key -> mCommonDataModel.setApiKey(key));
}
// For anything else, don't retry
return Observable.error(error);
}))
.subscribe(/* do what you need to do with the results*/)

为了添加副作用,即在您开始订阅时启用进度条,并在您完成某些操作后将其关闭

modifiedSource.doOnSubscribe(/* progress bar show logic */)
.doOnTerminate(/* progress bar dismiss logic */)

关于android - Retrofit RxAndroid 为 api 调用制作包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44883713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com