Android 集中式错误处理改造2?
在改造2之前,有一种集中处理错误的方法-Android 集中式错误处理改造2?,android,retrofit2,Android,Retrofit2,在改造2之前,有一种集中处理错误的方法- new retrofit.RestAdapter.Builder() .setEndpoint(apiUrl) .setLogLevel(retrofit.RestAdapter.LogLevel.FULL) .setErrorHandler(new CustomErrorHandler(ctx)) 但现在在改型2中,RestAdapter已重命名为reformation,并且没有setErrorHand
new retrofit.RestAdapter.Builder()
.setEndpoint(apiUrl)
.setLogLevel(retrofit.RestAdapter.LogLevel.FULL)
.setErrorHandler(new CustomErrorHandler(ctx))
但现在在改型2中,RestAdapter已重命名为
reformation
,并且没有setErrorHandler()
。是否有一种方法可以使用Reformation.Builder()
?Reformation 2.0移动错误处理程序并使用新的回调
,其中包括两种方法:
/** Successful HTTP response. */
public void onResponse(Response<T> response, Retrofit retrofit)````
/** Invoked when a network or unexpected exception occurred during the HTTP request. */
public void onFailure(Throwable t)
/**HTTP响应成功*/
公共响应(响应、改装)````
/**在HTTP请求期间发生网络或意外异常时调用*/
失效时的公共无效(可丢弃的t)
即使HTTP代码不是2xx或3xx,Reformation2.x仍将在onResponse
中接收所有HTTP响应,这里您需要检查onResponse
方法中的响应状态代码,并检查响应是否成功响应(通常为2xx或3xx)并进行正确的逻辑处理
我已经升级了Reformation2.x,我关于集中错误处理的解决方案是:
创建一个抽象类,该类使用onSuccess和onFailed两个方法扩展Reformation.Callback,onFailed不是抽象的,因为我总是在业务逻辑失败时执行相同的过程,在请求成功时执行不同的操作。
您可以参考示例代码
然后,当您需要发送http请求时,您需要实现onSuccess方法,并且您还可以在某些情况下覆盖onFailed方法,正如我在项目中提到的,在大多数情况下,我都以相同的方式处理失败的方法。
您可以参考我使用Reformation2发送post请求的示例
希望这能帮助你 我使用了Amir提出的类似解决方案,但我只是想知道这是否可以变得更简单。我尝试了以下方法:
public void onResponse(Response<T> response) {
if (response.isSuccess()) {
T resp = response.body();
handleSuccessResponse(resp);
} else {
Response<StatusResponse> statusResponse = response.error(response.code(), response.errorBody());
handleHttpErrorResponse(statusResponse);
}
}
public void onResponse(响应){
if(response.issucess()){
T resp=response.body();
handleSuccessResponse(resp);
}否则{
Response statusResponse=Response.error(Response.code(),Response.errorBody());
handleHttpErrorResponse(状态响应);
}
}
这样我就不需要到处传递改装实例了。但是,由于错误主体未成功解析为StatusResponse,所以我遗漏了一些内容。我不确定这在实践中意味着什么:
2.0.0-beta2中的更改为回调的onResponse回调提供了改造实例,该更改已恢复。为了允许错误体的反序列化,提供改装对象的边缘情况太多。为了适应这个用例,手动传递改装响应或实现自定义CallAdapter。Factory会自动这样做
好吧,您所要做的就是为故障情况使用自定义回调创建一个自定义的
调用适配器。改装repo有一个示例,显示了一个定制的CallAdapter
。你可以在
下面是一个显示自定义调用适配器的示例(不适用于2.2.0之前的版本):
/*
*版权所有(C)2015 Square,Inc。
*
*根据Apache许可证2.0版(以下简称“许可证”)获得许可;
*除非遵守许可证,否则不得使用此文件。
*您可以通过以下方式获得许可证副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*除非适用法律要求或书面同意,软件
*根据许可证进行的分发是按“原样”进行分发的,
*无任何明示或暗示的保证或条件。
*请参阅许可证以了解管理权限和权限的特定语言
*许可证下的限制。
*/
包com.example.inversion;
导入java.io.IOException;
导入java.lang.annotation.annotation;
导入java.lang.reflect.ParameterizedType;
导入java.lang.reflect.Type;
导入java.util.concurrent.Executor;
导入javax.annotation.Nullable;
2.电话;;
导入2.2.0适配器;
2.回拨;
进口改装2.converter.gson.GsonConverterFactory;
2.回应;;
进口改装2.改装;
导入文件2.http.GET;
/**
*显示自定义{@link CallAdapter}的示例,该自定义{@link CallAdapter}将内置{@link Call}调整为自定义
*其回调具有更细粒度方法的版本。
*/
公共最终类ErrorHandlingAdapter{
/**为各种条件提供细粒度回调的回调*/
接口MyCallback{
/**要求[200300]响应*/
无效成功(响应);
/**要求401个答复*/
未经验证无效(响应);
/**要求[400500]回复,401除外*/
void clientError(响应);
/**要求[500600]响应*/
无效服务器错误(响应);
/**呼叫时出现网络错误*/
无效网络错误(IOE例外);
/**呼叫时发生意外错误*/
无效意外错误(可丢弃的t);
}
接口MyCall{
作废取消();
无效排队(MyCallback);
mycallclone();
//留给读者作为练习。。。
//TODO MyResponse execute()抛出MyHttpException;
}
公共静态类ErrorHandlingCallAdapterFactory扩展CallAdapter.Factory{
@重写public@Nullable CallAdapter get(
类型返回类型,注释[]注释,改装(改装){
if(getRawType(returnType)!=MyCall.class){
返回null;
}
if(!(返回类型instanceof ParameterizedType)){
抛出新的非法状态异常(
“MyCall必须具有泛型类型(例如MyCall)”;
}
类型responseType=getParameterUpperBound(0,(ParameteredType)returnType);
Executor callbackExecutor=改装.callbackExecutor();
返回新的ErrorHandlingCallAdapter(responseType,callbackExecutor);
}
私有静态最终类ErrorHandlingCallAdapter实现CallAdapter{
P
/*
* Copyright (C) 2015 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.retrofit;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.Executor;
import javax.annotation.Nullable;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Callback;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.GET;
/**
* A sample showing a custom {@link CallAdapter} which adapts the built-in {@link Call} to a custom
* version whose callback has more granular methods.
*/
public final class ErrorHandlingAdapter {
/** A callback which offers granular callbacks for various conditions. */
interface MyCallback<T> {
/** Called for [200, 300) responses. */
void success(Response<T> response);
/** Called for 401 responses. */
void unauthenticated(Response<?> response);
/** Called for [400, 500) responses, except 401. */
void clientError(Response<?> response);
/** Called for [500, 600) response. */
void serverError(Response<?> response);
/** Called for network errors while making the call. */
void networkError(IOException e);
/** Called for unexpected errors while making the call. */
void unexpectedError(Throwable t);
}
interface MyCall<T> {
void cancel();
void enqueue(MyCallback<T> callback);
MyCall<T> clone();
// Left as an exercise for the reader...
// TODO MyResponse<T> execute() throws MyHttpException;
}
public static class ErrorHandlingCallAdapterFactory extends CallAdapter.Factory {
@Override public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != MyCall.class) {
return null;
}
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalStateException(
"MyCall must have generic type (e.g., MyCall<ResponseBody>)");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);
Executor callbackExecutor = retrofit.callbackExecutor();
return new ErrorHandlingCallAdapter<>(responseType, callbackExecutor);
}
private static final class ErrorHandlingCallAdapter<R> implements CallAdapter<R, MyCall<R>> {
private final Type responseType;
private final Executor callbackExecutor;
ErrorHandlingCallAdapter(Type responseType, Executor callbackExecutor) {
this.responseType = responseType;
this.callbackExecutor = callbackExecutor;
}
@Override public Type responseType() {
return responseType;
}
@Override public MyCall<R> adapt(Call<R> call) {
return new MyCallAdapter<>(call, callbackExecutor);
}
}
}
/** Adapts a {@link Call} to {@link MyCall}. */
static class MyCallAdapter<T> implements MyCall<T> {
private final Call<T> call;
private final Executor callbackExecutor;
MyCallAdapter(Call<T> call, Executor callbackExecutor) {
this.call = call;
this.callbackExecutor = callbackExecutor;
}
@Override public void cancel() {
call.cancel();
}
@Override public void enqueue(final MyCallback<T> callback) {
call.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, Response<T> response) {
// TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
int code = response.code();
if (code >= 200 && code < 300) {
callback.success(response);
} else if (code == 401) {
callback.unauthenticated(response);
} else if (code >= 400 && code < 500) {
callback.clientError(response);
} else if (code >= 500 && code < 600) {
callback.serverError(response);
} else {
callback.unexpectedError(new RuntimeException("Unexpected response " + response));
}
}
@Override public void onFailure(Call<T> call, Throwable t) {
// TODO if 'callbackExecutor' is not null, the 'callback' methods should be executed
// on that executor by submitting a Runnable. This is left as an exercise for the reader.
if (t instanceof IOException) {
callback.networkError((IOException) t);
} else {
callback.unexpectedError(t);
}
}
});
}
@Override public MyCall<T> clone() {
return new MyCallAdapter<>(call.clone(), callbackExecutor);
}
}
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://httpbin.org")
.addCallAdapterFactory(new ErrorHandlingCallAdapterFactory())
.addConverterFactory(GsonConverterFactory.create())
.build();
HttpBinService service = retrofit.create(HttpBinService.class);
MyCall<Ip> ip = service.getIp();
ip.enqueue(new MyCallback<Ip>() {
@Override public void success(Response<Ip> response) {
System.out.println("SUCCESS! " + response.body().origin);
}
@Override public void unauthenticated(Response<?> response) {
System.out.println("UNAUTHENTICATED");
}
@Override public void clientError(Response<?> response) {
System.out.println("CLIENT ERROR " + response.code() + " " + response.message());
}
@Override public void serverError(Response<?> response) {
System.out.println("SERVER ERROR " + response.code() + " " + response.message());
}
@Override public void networkError(IOException e) {
System.err.println("NETWORK ERROR " + e.getMessage());
}
@Override public void unexpectedError(Throwable t) {
System.err.println("FATAL ERROR " + t.getMessage());
}
});