Retrofit简要分析
Retrofit是对网络请求实现了一套请求架构封装,屏蔽底层网络实现,使网络请求像调用本地接口一样
基本使用例子
public interface GitHubService {//定义request方法以及返回需要的response类型 @GET("users/{user}/repos") List<Repo> listRepos(@Path("user") String user); @GET("users/{user}/repos") Call<List<Repo>> listRepos2(@Path("user") String user,Callback<List<Repo>> calback); } void usetest(){ static final String BASE_URL = "http://yourwebsite/services/"; Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())//Response转换器,这里以GsonConvert为例
.addCallAdapterFactory(Java8CallAdapterFactory.create())//request处理Adapter .build(); GitHubService service = retrofit.create(GitHubService.class); // 直接调用 List<Repo> data = service.listRepos("user1"); // 异步callback方式 service.listRepos2("user2",new Callback<List<Repo>>() { @Override public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) { data=response.body(); } @Override public void onFailure(Call<List<Repo>> call, Throwable t) { Log.e("error",t.getMessage()); } }); }
调用流程
分析调用实现:首先从create开始
public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service);//校验service接口定义是否合法 if (validateEagerly) { eagerlyValidateMethods(service); } return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },//产生代理,实现对service接口调用 new InvocationHandler() { private final Platform platform = Platform.get(); @Override public Object invoke(Object proxy, Method method, Object... args) throws Throwable { ... //每个接口最终转换为ServiceMethod,存储在serviceMethodCache中 ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method); //网络访问与okhttp结合生成OkHttpCall OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); //发起请求,返回结果,解析返回 return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
这里的OkHttpCall是Retrofit对自身Call接口实现,并不是okhttp3里的对象,通过实现接口内部封装okhttp3.Call,当然也可以替换其它网络库
看看call接口
public interface Call<T> extends Cloneable { ... Response<T> execute() throws IOException; ... void enqueue(Callback<T> callback); ... boolean isExecuted(); ... void cancel(); /** The original HTTP request. */ Request request(); }
与okhttp里面call类似,只不过自身重新定义一下,降低耦合度
看看Okhttp3实现类
final class OkHttpCall<T> implements Call<T> { private final ServiceMethod<T, ?> serviceMethod; private final Object[] args; private volatile boolean canceled; // All guarded by this. private okhttp3.Call rawCall; private Throwable creationFailure; // Either a RuntimeException or IOException. private boolean executed; OkHttpCall(ServiceMethod<T, ?> serviceMethod, Object[] args) { this.serviceMethod = serviceMethod; this.args = args; } ...... @Override public void enqueue(final Callback<T> callback) {//异步请求 if (callback == null) throw new NullPointerException("callback == null"); okhttp3.Call call; Throwable failure; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; ... if (failure != null) { callback.onFailure(this, failure); return; } if (canceled) { call.cancel(); } call.enqueue(new okhttp3.Callback() { @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException { Response<T> response; try { response = parseResponse(rawResponse);//解析response } catch (Throwable e) { callFailure(e); return; } callSuccess(response); } ...... }); } @Override public Response<T> execute() throws IOException {//同步调用请求 okhttp3.Call call; synchronized (this) { if (executed) throw new IllegalStateException("Already executed."); executed = true; ...... call = rawCall; if (call == null) { try { call = rawCall = createRawCall(); } catch (IOException | RuntimeException e) { creationFailure = e; throw e; } } } if (canceled) { call.cancel(); } return parseResponse(call.execute());//执行请求并解析 } private okhttp3.Call createRawCall() throws IOException { Request request = serviceMethod.toRequest(args); okhttp3.Call call = serviceMethod.callFactory.newCall(request); if (call == null) { throw new NullPointerException("Call.Factory returned null."); } return call; } Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException { ResponseBody rawBody = rawResponse.body(); // Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse.newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build(); ...... ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody); try { T body = serviceMethod.toResponse(catchingBody);//调用指定的Convert对response进行泛型转换 return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } }
convert最终调用来源Retrofit里的在builder里加入Converter.Factory
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast, Type type, Annotation[] annotations) { checkNotNull(type, "type == null"); checkNotNull(annotations, "annotations == null"); int start = converterFactories.indexOf(skipPast) + 1; for (int i = start, count = converterFactories.size(); i < count; i++) { Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter<ResponseBody, T>) converter; } } public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null")); return this; }
看看GsonResponseBodyConverter实现
final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter; GsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException {//通过TypeAdapter转换为对应实体类型T JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { return adapter.read(jsonReader); } finally { value.close(); } } }
整理一下,Retrofit使用Jdk里的Proxy动态代理方式实现对接口方法调用,即当调用接口方法listRepos时,调用了Proxy中的invoke,将对应接口方法及注解封装为ServiceMethod对象,通过CallAdapter对OkHttpCall调用获取Response并将数据转换为T返回给调用者
Retrofit中build构建方法:
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } okhttp3.Call.Factory callFactory = this.callFactory; if (callFactory == null) {//检测网络请求client,如果没有指定则创建一个client callFactory = new OkHttpClient(); } Executor callbackExecutor = this.callbackExecutor; if (callbackExecutor == null) {//回调执行callback的线程,如果没有指定则采用默认主线程 callbackExecutor = platform.defaultCallbackExecutor(); } //CallAdapter指的是对request处理的CallAdapter,可以添加多个 List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories); adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); // Converter是对response执行转换处理返回的T,可以添加多个 List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); }
CallAdapter接口定义
public interface CallAdapter<R, T> { //http 解析response 返回类型,不是咱接口定义泛型 Type responseType(); //处理response并转换为指定类型T T adapt(Call<R> call); //CallAdapter 创建获取 abstract class Factory { /** * Returns a call adapter for interface methods that return {@code returnType}, or null if it * cannot be handled by this factory. *根据接口返回类型,注解类型判断当前CallAdapter是否支持,不支持返回为null */ public abstract 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}. *获取指定index泛型参数上限,例如Map<String, ? extends Runnable> index为1参数上限为Runnable */ protected static 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}. */ //获取解析类型class,例如List<? extends Runnable>,返回List.class protected static Class<?> getRawType(Type type) { return Utils.getRawType(type); } }
项目中有三种实现
RxJava Observable & Single - com.squareup.retrofit2:adapter-rxjava
Guava ListenableFuture - com.squareup.retrofit2:adapter-guava
Java 8 CompleteableFuture - com.squareup.retrofit2:adapter-java8
看一下java8实现
Java8CallAdapterFactory
private static final class BodyCallAdapter<R> implements CallAdapter<R, CompletableFuture<R>> { private final Type responseType; BodyCallAdapter(Type responseType) { this.responseType = responseType; } @Override public Type responseType() { return responseType; } @Override public CompletableFuture<R> adapt(final Call<R> call) { final CompletableFuture<R> future = new CompletableFuture<R>() { @Override public boolean cancel(boolean mayInterruptIfRunning) { if (mayInterruptIfRunning) { call.cancel(); } return super.cancel(mayInterruptIfRunning); } }; call.enqueue(new Callback<R>() {//调用okhttp Call方法异步调用 @Override public void onResponse(Call<R> call, Response<R> response) { if (response.isSuccessful()) { future.complete(response.body()); } else { future.completeExceptionally(new HttpException(response)); } } @Override public void onFailure(Call<R> call, Throwable t) { future.completeExceptionally(t); } }); return future; } }
到这里我们已取到数据结果,再看看转换如何实现ServiceMethod的toResponse
/** Builds a method return value from an HTTP response body. */ R toResponse(ResponseBody body) throws IOException { return responseConverter.convert(body); }
通过serviceMethod 中的Converter<ResponseBody, R> responseConverter;实现进行解析
Converter为转换接口,实现类有以下
Gson - com.squareup.retrofit2:converter-gson
Jackson - com.squareup.retrofit2:converter-jackson
Moshi - com.squareup.retrofit2:converter-moshi
Protobuf - com.squareup.retrofit2:converter-protobuf
Wire - com.squareup.retrofit2:converter-wire
Simple Framework - com.squareup.retrofit2:converter-simpleframework
Scalars - com.squareup.retrofit2:converter-scalars
当然也可以自定义实现Converter,定制出符合自己需求转换器
从上面分析看出Retorfit中的3个核心部分:
1,Proxy 代理实现接口调用
2,CallAdapters request网络t处理
3,Converters response解析转换对应泛型T返回数据结果