这里先分享下我的好 gay 友 YoKey 的方案。youyou 的方案非常简洁,使用一个静态方法,方法里内部根据 server 端返回的 status 来分发错误。调用的时候,就像设置哨卡一样,在每个 API 请求的后面带上 RxResultHelper.handleResult() 即可(ps:就是遇到请求比较多的时候,需要设置好几个哨卡)。
我的方案
其实大体上和 youyou 是如出一辙的,就是设置哨卡的地方有点儿不太一样,这里我们再回忆下 API 的形式吧:
/** * Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are * created by {@linkplain Factory a factory} which is * {@linkplain Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit} * instance. */ publicinterfaceCallAdapter<R, T> { /** * Returns the value type that this adapter uses when converting the HTTP response body to a Java * object. For example, the response type for {@code Call<Repo>} is {@code Repo}. This type * is used to prepare the {@code call} passed to {@code #adapt}. * <p> * Note: This is typically not the same type as the {@code returnType} provided to this call * adapter's factory. */ Type responseType();
/** * Returns an instance of {@code T} which delegates to {@code call}. * <p> * For example, given an instance for a hypothetical utility, {@code Async}, this instance would * return a new {@code Async<R>} which invoked {@code call} when run. * <pre><code> * @Override * public <R> Async<R> adapt(final Call<R> call) { * return Async.create(new Callable<Response<R>>() { * @Override * public Response<R> call() throws Exception { * return call.execute(); * } * }); * } * </code></pre> */ T adapt(Call<R> call);
/** * Creates {@link CallAdapter} instances based on the return type of {@linkplain * Retrofit#create(Class) the service interface} methods. */ abstractclassFactory { /** * Returns a call adapter for interface methods that return {@code returnType}, or null if it * cannot be handled by this factory. */ publicabstract CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
/** * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}. */ protectedstatic Type getParameterUpperBound(int index, ParameterizedType type) { return Utils.getParameterUpperBound(index, type); }
/** * Extract the raw class type from {@code type}. For example, the type representing * {@code List<? extends Runnable>} returns {@code List.class}. */ protectedstatic Class<?> getRawType(Type type) { return Utils.getRawType(type); } } }
但是,别怕,泛型 R 代表是 ResponseBody,泛型 T 代表最终的转换类型,所以,我们的 CallAdapter 这么写: