gpt4 book ai didi

android - 集中式错误处理改造 2?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:01:59 25 4
gpt4 key购买 nike

在retrofit 2之前,有一种集中处理erros的方式——

new retrofit.RestAdapter.Builder()
.setEndpoint(apiUrl)
.setLogLevel(retrofit.RestAdapter.LogLevel.FULL)
.setErrorHandler(new CustomErrorHandler(ctx))

但是现在在Retrofit 2中,RestAdapter已经重命名为Retrofit并且没有setErrorHandler()。有没有办法使用 Retrofit.Builder() 集中处理错误?

最佳答案

好吧,您所要做的就是使用自定义回调创建自定义 CallAdapter,以应对失败情况。 Retrofit 存储库有一个显示自定义 CallAdapter 的示例。您可以在 retrofit/samples 找到它.

这是一个显示自定义 CallAdapter 的示例(不适用于 2.2.0 之前的版本):

/*
* 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());
}
});

关于android - 集中式错误处理改造 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35029936/

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