87.Retrofit源码解析

本文旨在用简短的代码块完成对Retrofit大体流程的解析,不求甚解,适可而止,以防走丢(っ•̀ω•́)っ✎⁾⁾

Retrofit是对OkHttp的封装,应用程序通过Retrofit请求网络,实际是使用Retrofit接口层封装请求参数,之后由OkHttp完成后续的请求操作,在服务端返回数据之后,OkHttp将原始的结果交给Retrofit,Retrofit根据用户的需求对结果进行解析

implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

public interface ApiService {
    @GET("users/{user}/repos")
    Call<List<Repo>> listRepos(@Query("user")String user);
}

	Retrofit retrofit = new Retrofit.Builder()
	        .baseUrl("https://api.github.com/")
	        .addConverterFactory(GsonConverterFactory.create())
	        .build();
	ApiService service = retrofit.create(ApiService.class);
	Call<List<Repo>> call = service.listRepos("xxx");
	call.enqueue(new Callback<List<Repo>>() {
	    @Override
	    public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
	    }
	    @Override
	    public void onFailure(Call<List<Repo>> call, Throwable t) {
	    }
	});

1.new Retrofit.Builder()
看一下Builder的构造方法

public Builder() {
    this(Platform.get());
}

class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

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

可以看到这里会得到一个平台类,包含Android或者Java8
回到开始,看一下baseUrl方法:

public Builder baseUrl(String baseUrl) {
    checkNotNull(baseUrl, "baseUrl == null");
    return baseUrl(HttpUrl.get(baseUrl));
}

public Builder baseUrl(HttpUrl baseUrl) {
    checkNotNull(baseUrl, "baseUrl == null");
    List<String> pathSegments = baseUrl.pathSegments();
    if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
    }
    this.baseUrl = baseUrl;
    return this;
}

可以看到baseUrl必须非空,并且以"/"结尾
回到开始,看一下addConverterFactory方法:

private final List<Converter.Factory> converterFactories = new ArrayList<>();

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

一个数据转换工厂的集合,看一下GsonConverterFactory.create()方法:

public static GsonConverterFactory create() {
    return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
    this.gson = gson;
}

会创建gson对象,用于数据解析
回到开始,看一下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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

    // Make a defensive copy of the converters.
    List<Converter.Factory> 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);
}

如果callFactory为空,会默认创建一个OkHttpClient对象;callbackExecutor回调执行器,若为空,调用platform.defaultCallbackExecutor()方法,因为我们是Android平台,找到Android类继承Platform:

static class Android extends Platform {
	@Override
	public Executor defaultCallbackExecutor() {
        return new MainThreadExecutor();
    }

    static class MainThreadExecutor implements Executor {
        private final Handler handler = new Handler(Looper.getMainLooper());
        @Override
        public void execute(Runnable r) {
            handler.post(r);
        }
    }
}

因为OkHttpClient数据回调在子线程,所以这个callbackExecutor是用于请求数据后,将线程切换到主线程
最后是请求适配器工厂集合callAdapterFactories和数据转换器converterFactories的初始化,将这些参数传入Retrofit中,返回Retrofit对象。

2.retrofit.create(ApiService.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();
            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);
          }
        });
}

validateServiceInterface方法就是对接口的判断抛出异常

static <T> void validateServiceInterface(Class<T> service) {
    if (!service.isInterface()) {
        throw new IllegalArgumentException("API declarations must be interfaces.");
    }
    // Prevent API interfaces from extending other interfaces. This not only avoids a bug in
    // Android (http://b.android.com/58753) but it forces composition of API declarations which is
    // the recommended pattern.
    if (service.getInterfaces().length > 0) {
        throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
    }
}

然后是eagerlyValidateMethods方法,提前验证

private void eagerlyValidateMethods(Class<?> service) {
    Platform platform = Platform.get();
    for (Method method : service.getDeclaredMethods()) {
        if (!platform.isDefaultMethod(method)) {
            loadServiceMethod(method);
        }
    }
}

boolean isDefaultMethod(Method method) {
    return false;
}

private final Map<Method, ServiceMethod<?>> 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;
}

对method做一个缓存,缓存到map中
Proxy.newProxyInstance是使用动态代理,直接看最后一行loadServiceMethod方法,如果缓存中有就从缓存取出,没有就put进去。追踪invoke方法,在HttpServiceMethod里,它继承了ServiceMethod:

final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    @Override
    ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
    }
}

进入adapt方法:

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

注意这里的Call是Retrofit库中的,而不是OkHttp里的Call,进入enqueue方法:

@Override
public void enqueue(final Callback<T> 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<T> 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();
        }
      }
    });
}

到这一步,这里的Call就是okhttp3.Call了,也就是说Retrofit是对OkHttp请求的进一步封装。请求完之后,会对响应值rawResponse进行解析,追踪parseResponse方法:

T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);

向下查找convert的实现,到GsonResponseBodyConverter类中,就是进行json解析的地方

@Override public T convert(ResponseBody value) throws IOException {
    JsonReader jsonReader = gson.newJsonReader(value.charStream());
    try {
      T result = adapter.read(jsonReader);
      if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonIOException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
      value.close();
    }
}

Retrofit源码解析到此戛然而止,这里是不求甚解的博主猴菇同学,咱们下期再见
在这里插入图片描述

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