Retrofit源码跟读

Retrofit官网

Retrofit的使用如下

1.Retrofit引用--在build.gradle中增加引用

   implementation 'com.squareup.retrofit2:retrofit:2.5.0'  //Retrofit
   implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//返回值转化成json

2.定义接口

public interface GitHubService {
    @GET("users/{user}/repos")
    Call> listRepos(@Path("user") String user);
}

3.请求

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com/") //必须以"/"结尾,不然将抛出异常
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GitHubService netApi = retrofit.create(GitHubService.class);
        Call> responseCall = netApi.listRepos("octocat");
        responseCall.enqueue(new Callback>() {
            @Override
            public void onResponse(Call> call, Response> response) {
                Log.e(TAG, "onResponse: =" + response.code());
            }

            @Override
            public void onFailure(Call> call, Throwable t) {
                Log.e(TAG, "onFailure: =" + t.toString());
            }
        });

4.结果返回值

 onResponse: =200

按照源码跟读如下:

查看responseCall.enqueue(Callback)方法,得知接口Call的方法,再向上追溯到netApi.listRepos("octocat"),属于接口调用方法返回Call值,再向上追溯retrofit.create(GitHubService.class)
源代码如下:

public  T create(final Class 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();
          private final Object[] emptyArgs = new Object[0];

          @Override public Object invoke(Object proxy, Method method, @Nullable 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)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

代码核心功能是:

  • 动态代理,调用接口方法时,就是调用new InvocationHandler()对象里的invoke的方法 ,核心就是调用loadServiceMethod(method).invoke(args != null ? args : emptyArgs)
到这里查看Retrofit代码使用,分两部分,一部分是通过Build模式生成Retrofit对象,一部分是使用Retrofit内的create方法,即使用动态代理处理接口的方法

首先我们从通过Build模式建立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 callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());
      converterFactories.addAll(this.converterFactories);
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
  • 对baseUrl判断是否为null
  • callFactory变量对应的是okhttp3.call.Factory类型,默认初始化的实现是okhttp3的OkHttpClient对象
  • callbackExecutor变量对象的是java.util.concurrent.Executor类型,默认初始化的实现是platform.defaultCallbackExecutor();其中platform通过Build()构造函数知道是在retrofit2.Platform类里实现的是Android内部类,而其中defaultCallbackExecutor()方法返回的是MainThreadExecutor类得知,是通过handler切换线程到主线程
private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }
 static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  • callAdapterFactories变量对应的的是retrofit2.CallAdapter.Factory,该变量用来适配网络请求,例如适配RxJava2CallAdapterFactory
  • converterFactories 变量对应的是retrofit2.Converter.Factory,该变量用来适配数据转换,例如适配GsonConverterFactory.create(),其中会有默认的数据解析器 converterFactories.add(new BuiltInConverters());

查看Retrofit类的create(final Class service)方法内的loadServiceMethod(method).invoke(args != null ? args : emptyArgs)

 private final Map> serviceMethodCache = new ConcurrentHashMap<>();
 ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }
  • ConcurrentHashMap是HashMap的一个线程安全的,用来缓存ServiceMethod;根据Method判断是否有缓存,有则直接取出来;否则通过ServiceMethod.parseAnnotations(this, method)重新创建,并缓存起来
abstract class ServiceMethod {
  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);

    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      throw methodError(method,
          "Method return type must not include a type variable or wildcard: %s", returnType);
    }
    if (returnType == void.class) {
      throw methodError(method, "Service methods cannot return void.");
    }

    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  abstract T invoke(Object[] args);
}
  • RequestFactory.parseAnnotations(retrofit, method)返回的RequestFactory类是注解相关的数据
final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }

  private final Method method;    //方法
  private final HttpUrl baseUrl; //基地址
  final String httpMethod; //请求方法,即get  post  delete
  private final @Nullable String relativeUrl;  //方法的相对地址,即path部分
  private final @Nullable Headers headers;  // 注解的header内容,请求头
  private final @Nullable MediaType contentType; //请求体
  private final boolean hasBody; //是否有请求体
  private final boolean isFormEncoded;  //是否是表单
  private final boolean isMultipart; //是否图片类
  private final ParameterHandler[] parameterHandlers;//方法参数处理器
  • Retrofit不是网络请求框架,是封装的Okhttp的请求框架,通过注解拿到请求参数封装后由okhttp3请求,所以该类是解析各种注解,获取到请求的各种方法;requestFactory是注解的相关参数
  • HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)方法确定HttpServiceMethod类是ServiceMethod的实现类,包括Invoke方法
static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    CallAdapter callAdapter = createCallAdapter(retrofit, method);
    Type responseType = callAdapter.responseType();
    if (responseType == Response.class || responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + Utils.getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
  }
  • 构建函数HttpServiceMethod对象的四个变量requestFactory是注解对应的方法及参数,callFactory是Retrofit里对应的OkHttpClient对象
  • callAdapter的创建代码如下:
  private static  CallAdapter createCallAdapter(
      Retrofit retrofit, Method method) {
    Type returnType = method.getGenericReturnType();
    Annotation[] annotations = method.getAnnotations();
    try {
      //noinspection unchecked
      return (CallAdapter) retrofit.callAdapter(returnType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create call adapter for %s", returnType);
    }
  }
  • 首先从网络请求接口方法中获取注释,然后根据注释和注释返回类型,接着调用retrofit.callAdapter()方法从retrofit中获取适配器。咱们跟着代码会发发现其实最后调用的是retrofit的nextCallAdapter()
public CallAdapter nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      CallAdapter adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
...
  }
  • 在for循环中,根据请求参数在网络适配工厂中创建网络适配器并返回该适配器
  • responseConverter变量的创建代码如下:
  private static  Converter createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
  }

最终还是到Retrofit类中nextResponseBodyConverter方法

public  Converter nextResponseBodyConverter(
      @Nullable 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 converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter) converter;
      }
    }
...
  }
  • 可以看到,和创建网络请求适配器一样的创建方法,根据响应类型和请求方法注释数值,从数据转换器工厂中创建数据转换器并返回
至此loadServiceMethod(method)已完成,创建并返回ServiceMethod的实现类HttpServiceMethod,做的内容包括:解析网络请求接口参数、网络请求适配器、response数据解析器等工作
  • 查看HttpServiceMethod的invoke方法
创建OkHttpCall对象new OkHttpCall<>(requestFactory, args, callFactory, responseConverter)

由于retrofit的网络请求是由okhttp3请求,所以OkHttpCall就是对okhttp的call对象的封装,OkHttpCall对象的同步及异步代码如下:

//网络请求异步操作方法
@Override 
public void enqueue(final Callback callback) {
    checkNotNull(callback, "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) {
          throwIfFatal(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) {
        Response response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        callFailure(e);
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }

//网络请求同步操作方法
  @Override public Response execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
          throw (IOException) creationFailure;
        } else if (creationFailure instanceof RuntimeException) {
          throw (RuntimeException) creationFailure;
        } else {
          throw (Error) creationFailure;
        }
      }

      call = rawCall;
      if (call == null) {
        try {
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException | Error e) {
          throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }

    return parseResponse(call.execute());
  }
  • 不管是同步还是异步,都创建了okhttp3.call rawCall变量,最终调用都是rawCall的同步或者异步方法,也就是okhttp3.Call的enqueue()和execute()
callAdapter.adapt(okHttpCall)

这个方法很显然使用适配器模式,将某些咱们需要处理的事件,适配成其他平台可以使用的类型,并在该平台使用。这里调用serviceMethod的adapt适配方法,传入了上面步骤7中创建的OkHttpCall实例,并将适配对象返回;比如可以使用RxJava2CallAdapterFactory.create()来创建了一个RxJava2CallAdapter的适配器来适配RxJava2平台,适配成RxJava2平台能使用的Call

咱们接下来看Retrofit的CallAdapter接口中的Rxjava2CallAdapter实现类的adapter()方法:
package retrofit2.adapter.rxjava2;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Observable;
import io.reactivex.Scheduler;
import java.lang.reflect.Type;
import javax.annotation.Nullable;
import retrofit2.Call;
import retrofit2.CallAdapter;
import retrofit2.Response;

final class RxJava2CallAdapter implements CallAdapter {
  private final Type responseType;


  @Override public Object adapt(Call call) {
    Observable> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

    Observable observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return observable;
  }
}
  • 该适配方法返回了一个Observable被观察者对象

你可能感兴趣的:(Retrofit源码跟读)