retrofit2源码分析

来源:互联网 发布:网络直播学校 编辑:程序博客网 时间:2024/06/06 00:53

如果对retrofit使用不太了解的可以去网上查一些资料,本篇就直接对源码进行分析了。
一、首先你需要RestfulApi 类,里面声明了咱们的请求

public interface RestfulApi {    // 获取时间戳    @POST("app.do?")    Call<T> getTime(@Query("pattern") String pattern);}

然后封装Retrofit

public class HttpClient {    private RestfulApi apiService;    private OkHttpClient okHttpClient;    public HttpClient(Context context) {        okHttpClient = genericClient();        Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)                .addConverterFactory(GsonConverterFactory.create())                .client(okHttpClient)                .build();        apiService = retrofit.create(RestfulApi.class);    }    // 创建OkHttpClient实例    private OkHttpClient genericClient() {        return new OkHttpClient.Builder().                addInterceptor(new HttpInterceptor())                .connectTimeout(30, TimeUnit.SECONDS)                .readTimeout(30, TimeUnit.SECONDS)                .writeTimeout(30, TimeUnit.SECONDS)                .build();    }}

然后调用异步接口就是

Call<T> call = apiService.getTime(pattern);call.enqueue(callback);

二、下边针对retrofit2进行源码分析

// 创建OkHttpClient实例    private OkHttpClient genericClient() {        return new OkHttpClient.Builder().                addInterceptor(new HttpInterceptor())                .connectTimeout(30, TimeUnit.SECONDS)                .readTimeout(30, TimeUnit.SECONDS)                .writeTimeout(30, TimeUnit.SECONDS)                .build();    }

这一段代码很明显是对OkHttp中OkHttpClient的初始化,对OkHttp不了解可以看下
OkHttp3源码分析

Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)                .addConverterFactory(GsonConverterFactory.create())                .client(okHttpClient)                .build();

这一段代码是对Retrofit的初始化

addConverterFactory(GsonConverterFactory.create())//对返回的数据支持json格式解析
client(okHttpClient)//设置okhttp3.Call.Factory callFactory = okHttpClient

最主要的就是下面这段代码

apiService = retrofit.create(RestfulApi.class);

查看源码

public <T> T create(final Class<T> service) {    Utils.validateServiceInterface(service);    if (validateEagerly) {      eagerlyValidateMethods(service);    }    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },        new InvocationHandler() {          private final Platform platform = Platform.get();          @Override public Object invoke(Object proxy, Method method, Object... args)              throws Throwable {            // If the method is a method from Object then defer to normal invocation.            if (method.getDeclaringClass() == Object.class) {//反射获取到的类全名称              return method.invoke(this, args);            }            if (platform.isDefaultMethod(method)) {//Android/ios返回false,java8返回true              return platform.invokeDefaultMethod(method, service, proxy, args);            }            //组装ServiceMethod,里面有缓存,一样的方法只会执行一次,这个很大程度上优化了性能,因为反射是会消耗性能的            ServiceMethod serviceMethod = loadServiceMethod(method);            //传入的serviceMethod和参数            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);            return serviceMethod.callAdapter.adapt(okHttpCall);          }        });  }

发现上面是典型的Java动态代理
看上面的注释,Android中一定会走到下面,直接分析下面重要代码

ServiceMethod serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {    ServiceMethod result;    synchronized (serviceMethodCache) {      result = serviceMethodCache.get(method);//从缓存中获取serviceMethod      if (result == null) {        result = new ServiceMethod.Builder(this, method).build();        serviceMethodCache.put(method, result);      }    }    return result;  }

由于动态代理是用的反射的原理,然而所有的反射都有性能消耗,这里对method进行了缓存,每个方法只会运行一次

private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

final修饰,引用地址不可变,这里用了LinkedHashMap表示不是很理解,LinkedHashMap底层是链表实现的,哪位朋友知道评论一下

//TODO

ServiceMethod里面的代码暂缓,等下再分析

OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);

看一下OkHttpCall的构造器

OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {    this.serviceMethod = serviceMethod;    this.args = args;  }

只是把刚声明的ServiceMethod和args参数传过去

serviceMethod.callAdapter.adapt(okHttpCall);

三、分析问题
1、serviceMethod.callAdapter是什么?
2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

先分析一下第一个问题

首先看ServiceMethod的build()里

public ServiceMethod build() {      callAdapter = createCallAdapter()
private CallAdapter<?> createCallAdapter() {      Type returnType = method.getGenericReturnType();      if (Utils.hasUnresolvableType(returnType)) {        throw methodError(            "Method return type must not include a type variable or wildcard: %s", returnType);      }      if (returnType == void.class) {        throw methodError("Service methods cannot return void.");      }      Annotation[] annotations = method.getAnnotations();      try {        return retrofit.callAdapter(returnType, annotations);      } catch (RuntimeException e) { // Wide exception range because factories are user code.        throw methodError(e, "Unable to create call adapter for %s", returnType);      }    }

跑到了Retrofit类里

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {    return nextCallAdapter(null, returnType, annotations);  }
public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,      Annotation[] annotations) {    checkNotNull(returnType, "returnType == null");    checkNotNull(annotations, "annotations == null");    int start = adapterFactories.indexOf(skipPast) + 1;    for (int i = start, count = adapterFactories.size(); i < count; i++) {      CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//ExecutorCallAdapterFactory   执行      if (adapter != null) {        return adapter;      }    }    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")        .append(returnType)        .append(".\n");    if (skipPast != null) {      builder.append("  Skipped:");      for (int i = 0; i < start; i++) {        builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());      }      builder.append('\n');    }    builder.append("  Tried:");    for (int i = start, count = adapterFactories.size(); i < count; i++) {      builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());    }    throw new IllegalArgumentException(builder.toString());  }

最后走到了nextCallAdapter里,然后看只是从adapterFactories里取数据,看一下adapterFactories是什么

看一下Retrofit的build

public Retrofit build() {      if (baseUrl == null) {        throw new IllegalStateException("Base URL required.");      }      okhttp3.Call.Factory callFactory = this.callFactory;      if (callFactory == null) {        callFactory = new OkHttpClient();      }      Executor callbackExecutor = this.callbackExecutor;      if (callbackExecutor == null) {        callbackExecutor = platform.defaultCallbackExecutor();      }      // Make a defensive copy of the adapters and add the default Call adapter.      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));      // Make a defensive copy of the converters.      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,          callbackExecutor, validateEagerly);    }  }

重点看一下

Executor callbackExecutor = this.callbackExecutor;      if (callbackExecutor == null) {        callbackExecutor = platform.defaultCallbackExecutor();      }      // Make a defensive copy of the adapters and add the default Call adapter.      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

看一下Android的Platform

static class Android extends Platform {    @Override public Executor defaultCallbackExecutor() {      return new MainThreadExecutor();    }    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {      return new ExecutorCallAdapterFactory(callbackExecutor);    }    static class MainThreadExecutor implements Executor {      private final Handler handler = new Handler(Looper.getMainLooper());      @Override public void execute(Runnable r) {        handler.post(r);      }    }  }

callbackExecutor = platform.defaultCallbackExecutor() = new MainThreadExecutor();
由于MainThreadExecutor里的handler创建的Looper是主线程里的,so handler也是主线程(UI线程)里的,对Android的异步消息机制不了解的可以看下异步消息机制

看到没最后把UI线程赋值给了callbackExecutor

adapterFactories最后add的是ExecutorCallAdapterFactory

然后再回过头来

CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//等同于CallAdapter<?> adapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);

看一下ExecutorCallAdapterFactory类

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {  final Executor callbackExecutor;//MainThreadExecutor 主线程  ExecutorCallAdapterFactory(Executor callbackExecutor) {    this.callbackExecutor = callbackExecutor;  }  @Override  public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {    if (getRawType(returnType) != Call.class) {      return null;    }    final Type responseType = Utils.getCallResponseType(returnType);    return new CallAdapter<Call<?>>() {      @Override public Type responseType() {        return responseType;      }      @Override public <R> Call<R> adapt(Call<R> call) {        return new ExecutorCallbackCall<>(callbackExecutor, call);      }    };  }  static final class ExecutorCallbackCall<T> implements Call<T> {    final Executor callbackExecutor;    final Call<T> delegate;    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {      this.callbackExecutor = callbackExecutor;//主线程      this.delegate = delegate;//okhttpCall    }    @Override public void enqueue(final Callback<T> callback) {      if (callback == null) throw new NullPointerException("callback == null");      delegate.enqueue(new Callback<T>() {        @Override public void onResponse(Call<T> call, final Response<T> response) {          callbackExecutor.execute(new Runnable() {            @Override public void run() {              if (delegate.isCanceled()) {                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));              } else {                callback.onResponse(ExecutorCallbackCall.this, response);              }            }          });        }        @Override public void onFailure(Call<T> call, final Throwable t) {          callbackExecutor.execute(new Runnable() {            @Override public void run() {              callback.onFailure(ExecutorCallbackCall.this, t);            }          });        }      });    }    @Override public boolean isExecuted() {      return delegate.isExecuted();    }    @Override public Response<T> execute() throws IOException {      return delegate.execute();    }    @Override public void cancel() {      delegate.cancel();    }    @Override public boolean isCanceled() {      return delegate.isCanceled();    }    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.    @Override public Call<T> clone() {      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());    }    @Override public Request request() {      return delegate.request();    }  }}

回过头来看一下问题
1、serviceMethod.callAdapter是什么?
2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

答案:
serviceMethod.callAdapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);

callbackExecutor = MainThreadExecutor,这个是retrofit里传进来的

serviceMethod.callAdapter.adapt(okHttpCall) = ExecutorCallAdapterFactory.get(returnType, annotations, this).adapt(okHttpCall) = new ExecutorCallbackCall<>(callbackExecutor, okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall)


回过头来看一下我们业务层写的请求

Call<T> call = apiService.getTime(pattern);call.enqueue(listener);

call = serviceMethod.callAdapter.adapt(okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall);

call.enqueue(callback) = ExecutorCallbackCall.enqueue(callback)

最后走到了OkHttpCall里,各位看官请看

delegate = OkHttpCall.enqueue(new Callback<T>() {        @Override public void onResponse(Call<T> call, final Response<T> response) {          callbackExecutor.execute(new Runnable() {            @Override public void run() {              if (delegate.isCanceled()) {                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));              } else {                callback.onResponse(ExecutorCallbackCall.this, response);              }            }          });        }        @Override public void onFailure(Call<T> call, final Throwable t) {          callbackExecutor.execute(new Runnable() {            @Override public void run() {              callback.onFailure(ExecutorCallbackCall.this, t);            }          });        }      });

搞一段落,终于搞清楚了,最后代码会走到OkHttpCall.enqueue();

分析一下OkHttpCall.enqueue()

@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;      call = rawCall;      failure = creationFailure;      if (call == null && failure == null) {        try {          call = rawCall = createRawCall();        } catch (Throwable t) {          failure = creationFailure = t;        }      }    }    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);        } catch (Throwable e) {          callFailure(e);          return;        }        callSuccess(response);      }      @Override public void onFailure(okhttp3.Call call, IOException e) {        try {          callback.onFailure(OkHttpCall.this, e);        } catch (Throwable t) {          t.printStackTrace();        }      }      private void callFailure(Throwable e) {        try {          callback.onFailure(OkHttpCall.this, e);        } catch (Throwable t) {          t.printStackTrace();        }      }      private void callSuccess(Response<T> response) {        try {          callback.onResponse(OkHttpCall.this, response);        } catch (Throwable t) {          t.printStackTrace();        }      }    });  }
private okhttp3.Call createRawCall() throws IOException {    Request request = serviceMethod.toRequest(args);    okhttp3.Call call = serviceMethod.callFactory.newCall(request);//serviceMethod.callFactory是okhttpClient    if (call == null) {      throw new NullPointerException("Call.Factory returned null.");    }    return call;  }

ServiceMethod的builder

ServiceMethod(Builder<T> builder) {    this.callFactory = builder.retrofit.callFactory();

Retrofit里的

    public Builder client(OkHttpClient client) {      return callFactory(checkNotNull(client, "client == null"));    }    /**     * Specify a custom call factory for creating {@link Call} instances.     * <p>     * Note: Calling {@link #client} automatically sets this value.     */    public Builder callFactory(okhttp3.Call.Factory factory) {      this.callFactory = checkNotNull(factory, "factory == null");      return this;    }

这里面的逻辑其实就是走到了OkHttp里的RealCall.enqueue,然后再解析,回调。
对OkHttp不是很了解可以看下OkHttp源码分析

对源码逻辑明白了,但是想一想设计者为什么要这样设计retrofit,你会学到的更多。

retrofit的设计模式这篇文章写的特别好。
盗用一下图
这里写图片描述

真的是很美妙啊啊……..

原创粉丝点击