1. 程式人生 > >Android Retrofit 原始碼解析

Android Retrofit 原始碼解析

1,Retrofit的建立過程

(1) 介面

public interface RestService {
  
    @GET
    Call<String> get(@Url String url, @QueryMap WeakHashMap<String, Object> params);
   ......
}

(2) Retrofit 

Retrofit retrofit = new Retrofit.Builder()
           .baseUrl(url)              
           .addConverterFactory(GsonConverterFactory.create())
           .build();
}
 public Builder() {
      this(Platform.get());
 }

在Platform中根據不同的執行平臺選擇不同的執行緒池

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

  @Nullable Executor defaultCallbackExecutor() {
    return null;
  }

  CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
    if (callbackExecutor != null) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }
    return DefaultCallAdapterFactory.INSTANCE;
  }

  boolean isDefaultMethod(Method method) {
    return false;
  }

  @Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
      @Nullable Object... args) throws Throwable {
    throw new UnsupportedOperationException();
  }

  ......

  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);
      }
    }
  }
}
    public Retrofit build() {
       //url不能為空
      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.
        //儲存對call轉化的物件
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

        //儲存轉化資料的物件,比如GsonConverterFactory
      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }

2,Call的建立過程

 RestService service = retrift.create(RestService.class);
 public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    ......
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
            //第一個引數代理物件,第二個引數是呼叫方法,上面定義的get,第三個引數為方法引數
          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
           ......
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //對call進行封裝,返回call,新增callbackExecutor將請求返回到UI執行緒           
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }
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 = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }
    public ServiceMethod build() {
      callAdapter = createCallAdapter();
      //返回資料的真實型別
      responseType = callAdapter.responseType();
      ......
      //返回一個合適的Converter來轉換物件
      responseConverter = createResponseConverter();
      //遍歷methodAnnotations來對請求方式和請求地址進行解析
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }

      ......
      
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        ......
        //對方法中的引數進行解析
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        ......

        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
      }

      ......
      return new ServiceMethod<>(this);
    }

3,Call的enqueue方法

 @Override public void enqueue(final Callback<T> callback) {

    okhttp3.Call call;
    Throwable failure;

    ......

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

     ......
    });
  }
  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }

    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
        //呼叫convertor對資料轉換
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }
R toResponse(ResponseBody body) throws IOException {
    return responseConverter.convert(body);
  }