retrofit2源码分析

如果对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的设计模式这篇文章写的特别好。
盗用一下图
这里写图片描述

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值