学习笔记

Retrofit 源码分析
Publish: 2018/7/23   

根据Retrofit使用,分析每一步相关源码

Api api = new Retrofit.Builder()
    .baseUrl(BASE_URL)//配置生产或测试环境
    .client(getOkHttpClient())//HTTP 请求
    .addConverterFactory(GsonConverterFactory.create(new Gson()))//参数对象和json转换器
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//Call转换为Rxjava的Observable
    .build()//初始化参数,创建retrofit
    .create(Api.class);//返回接口实现                        

Builder()

public Builder() {
    /*Platform->findPlatform()->return new Android();*/        
      this(Platform.get());
    }

addConverterFactory(GsonConverterFactory.create(new Gson()))

public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

默认只支持ResponseBody,可以使用下面6种方式实现对象的序列化和反序列化转换

addCallAdapterFactory(RxJava2CallAdapterFactory.create())

可以将调用Api方法返回的Call转换为RxJava的Observable, Flowable, Single, Completable or Maybe

/**
 * Add a call adapter factory for supporting service method return types other than {@link
 * Call}.
 */
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
* Call->调用Retrofit方法,将请求发送到Web服务器并返回响应
    /*调用Retrofit方法,将请求发送到Web服务器并返回响应
    继承Cloneable,使用相同的参数对同一个网络请求多次调用,可以用来轮询或失败重试
    */
    public interface Call extends Cloneable {
        Response execute() throws IOException;//同步执行

        void enqueue(Callback callback);//异步执行

        boolean isExecuted();//如果此调用执行或已排队返回true,多次调用会报错

        void cancel();//不管是执行中还是在排队中,都取消此次调用的执行

        boolean isCanceled();//cancel()被调用返回true

        Call clone();//克隆这个调用,即使调用已经结束,也可以调用或排队

        Request request();//执行http请求
    }
    

build()

检查参数,如果Null设置默认值,创建retrofit对象

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

      // 添加自定义转换器(RxJava2CallAdapterFactory)和默认的转换器(Android->ExecutorCallAdapterFactory)
      List adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(this.converterFactories);
      //retrofit只有一个构造方法
      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
只有callbackExecutor在之前没有是设置,这里调用platform.defaultCallbackExecutor(); 其实就是Android里方法,通过主线程的Handler执行网络访问 * Executor:执行提交的Runnable任务的对象。 该接口提供了一种将任务提交与每个任务如何运行的机制解耦的方式,包括线程使用,调度等细节
static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
      if (callbackExecutor == null) throw new AssertionError();
      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);
      }
    }
  }

create(Api.class);

使用动态代理实现接口方法的调用

public  T create(final Class service) {
    Utils.validateServiceInterface(service);//service 必须是接口并且不能有父类
    if (validateEagerly) {//默认false
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();//获得Android

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // 如果是Object的方法,遵循正常调用
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {//Android 未重写该方法 默认是false
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            // 下面是主要的接口方法实现 
            ServiceMethod serviceMethod =
                (ServiceMethod) loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

loadServiceMethod(method);//将method和ServiceMethod用ConcurrentHashMap缓存,提高效率
    ->ServiceMethod loadServiceMethod(Method method) {
          //serviceMethodCache = new ConcurrentHashMap<>();
        ServiceMethod result = serviceMethodCache.get(method);
        if (result != null) return result;

        synchronized (serviceMethodCache) {
          result = serviceMethodCache.get(method);
          if (result == null) {
            result = new ServiceMethod.Builder<>(this, method).build();
            serviceMethodCache.put(method, result);
          }
        }
        return result;
      }

ConcurrentHashMap采用分段锁,并发操作效率更高,线程安全

ServiceMethod

将接口方法的调用调整为HTTP调用。

//通过Build方式实例化
Builder(Retrofit retrofit, Method method) {
    this.retrofit = retrofit;
    this.method = method;
    this.methodAnnotations = method.getAnnotations();//获取方法的的注解
    this.parameterTypes = method.getGenericParameterTypes();//获取方法注解类型
    this.parameterAnnotationsArray = method.getParameterAnnotations();//获取方法参数注解
}        
build();初始化参数并校验

将普通的接口方法返回类型Call转换为需要的类型

1、如果有自定义callAdapter,返回自定义callAdapter

2、如果没有就返回默认的CallAdapter(Android->ExecutorCallAdapterFactory)

return (CallAdapter) retrofit.callAdapter(returnType, annotations);
->Retrofit->return nextCallAdapter(null, returnType, annotations);
1、自定义转换器(RxJava2CallAdapterFactory):返回对应的接口方法返回值类型,如Observable

2、默认的转换器(Android->ExecutorCallAdapterFactory)
->ExecutorCallAdapterFactory->get()
->return new CallAdapter>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call adapt(Call call) {
        //serviceMethod.callAdapter.adapt(okHttpCall);最终是在这里执行
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
* responseConverter = createResponseConverter();//实现json和对象的相互转换
return retrofit.responseBodyConverter(responseType, annotations);
->Retrofit->return nextResponseBodyConverter(null, type, annotations);
->GsonConverterFactory->return new GsonResponseBodyConverter<>(gson, adapter);
->final class GsonResponseBodyConverter implements Converter {
  private final Gson gson;
  private final TypeAdapter adapter;

  GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) {
    this.gson = gson;
    this.adapter = adapter;
  }

  @Override public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      return adapter.read(jsonReader);
    } finally {
      value.close();
    }
  }
}
->parseHttpMethodAndPath()获得请求方式:POST、GET或者parseHeaders()获得请求头信息headers

OkHttpCall

通过RxJava2CallAdapterFactory将OkHttpCall交由Rxjava处理

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

->okhttp3.Call call = rawCall = rawCall = createRawCall();
->private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    //这里将自定义OkhttpLCient与retrofit关联起来
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }


← 国际化适配笔记 The Programmer's Oath →

Powered by Hexo, Theme designs by @hpcslag.
Style-Framework Tocas-UI designs by @yamioldmel