簡(jiǎn)單說(shuō)一下Retrofit2源碼

在說(shuō)Retrofit之前 必須有了解動(dòng)態(tài)代理,因?yàn)镽etrofit的核心就是動(dòng)態(tài)代理。

動(dòng)態(tài)代理

  • 動(dòng)態(tài)代理就是在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建某個(gè)interface的實(shí)例,通過(guò)Proxy.newProxyInstance產(chǎn)生代理類(lèi),調(diào)用接口的任何方法的時(shí)候,都會(huì)被InvocationHandler的invoke方法攔截,拿到傳輸?shù)膮?shù)信息,可以做一些相應(yīng)的處理。

Retrofit的Calladapter和Converter兩個(gè)重要的對(duì)象

  • calladapter 是適配器,幫助我們返回是適配返回的類(lèi)型,
  • Converter 數(shù)據(jù)組裝器,負(fù)責(zé)把服務(wù)器返回的數(shù)據(jù)ResponseBody轉(zhuǎn)換成T對(duì)象。
  1. 先看一下創(chuàng)建過(guò)程 也就是create
public <T> T create(final Class<T> service) {
    validateServiceInterface(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 @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                args = args != null ? args : emptyArgs;
                
                return platform.isDefaultMethod(method)
                    ? platform.invokeDefaultMethod(method, service, proxy, args)
                    : loadServiceMethod(method).invoke(args);
              }
            });
  }

retrofit 的creat 主要是動(dòng)態(tài)代理模式,invoke方法。然后就是核心:loadServiceMethod(method)和 invoke(args)

  1. loadServiceMethod
    這個(gè)方法主要將網(wǎng)絡(luò)請(qǐng)求中的信息初步做處理,在api service中注解(@POST @GET)還有參數(shù),進(jìn)行解析,解析后有生成了一個(gè)RequestFactory的工廠對(duì)象,并利用這個(gè)對(duì)象創(chuàng)建了CallAdapter。
  2. invoke(args)
final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

主要是根絕loadserviceMethod 創(chuàng)建的RequestFactory 以及轉(zhuǎn)換的參數(shù) 生產(chǎn)一個(gè)OkhttpCall對(duì)象。其實(shí)這個(gè)OkhttpCall對(duì)象就是對(duì)OKhttp RealCall的一個(gè)包裝。

看一下OkhttpCall的網(wǎng)絡(luò)請(qǐng)求:

@Override
  public void enqueue(final Callback<T> callback) {
    Objects.requireNonNull(callback, "callback == null");

    okhttp3.Call call;
    synchronized (this) {
      ...
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall();
        }
      }
    ...
    call.enqueue(
        new okhttp3.Callback() {
          @Override
          public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
            Response<T> response;
            try {
              //解析請(qǐng)求返回值
              response = parseResponse(rawResponse);
            }
              ...
            try {
              callback.onResponse(OkHttpCall.this, response);
            }

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

          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            }
          }
        });
  }
  1. 調(diào)用了一個(gè)createRawCall()方法,創(chuàng)建rawCall,這個(gè)rawCall其實(shí)指代的就是Okhttp3的call,也就是OkHttp進(jìn)行網(wǎng)絡(luò)請(qǐng)求調(diào)用的一個(gè)調(diào)度器.
  2. 創(chuàng)建好OkHttp的call后,就開(kāi)始調(diào)用enqueue進(jìn)行異步請(qǐng)求.
    3.okhttp3.Response這個(gè)響應(yīng),retrofit在收到結(jié)果后,進(jìn)行新一輪的解析 response = parseResponse(rawResponse),以Response對(duì)象的形式返回給開(kāi)發(fā)者。

CallAdapted

loadserviceMethod 返回的是CallAdapted對(duì)象。

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {

  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {

    Type adapterType;
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType =
          Utils.getParameterLowerBound(
              0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();
    }

    CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
  ...

    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    }

public CallAdapter<?, ?> nextCallAdapter(
      @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
    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;
      }
    }

CallAdapter根據(jù)returnType和annotation的類(lèi)型,從calladapterfactories中進(jìn)行查找,返回所對(duì)應(yīng)的網(wǎng)絡(luò)請(qǐng)求適配器。
總結(jié)一下:

  1. 開(kāi)始動(dòng)態(tài)代理調(diào)用loadServiceMethod方法,解析接口中的注解參數(shù)和頭部信息。
  2. 根絕接口返回類(lèi)型,從適配工廠集合中查詢(xún),生產(chǎn)相應(yīng)的適配器CallAdapter,相同的形式取出數(shù)據(jù)轉(zhuǎn)換器Converter。
  3. 用生產(chǎn)的CallAdapter 調(diào)用invoke方法,創(chuàng)建okhttpCall對(duì)象,然后進(jìn)行網(wǎng)絡(luò)請(qǐng)求,響應(yīng)結(jié)果進(jìn)行實(shí)體類(lèi)轉(zhuǎn)換,
  4. 創(chuàng)建好okhttpcall以后 調(diào)用CallAdapter的adapter,返回Rxjava的Observable.single或者call對(duì)象。

Retrofit結(jié)合動(dòng)態(tài)代理,不用關(guān)心真正的接口方法,對(duì)符合規(guī)范的接口進(jìn)行統(tǒng)一管理,以統(tǒng)一注解的方式和參數(shù),拼接成request的請(qǐng)求。

retrofit是怎么將子線程切換到主線程

  1. 添加默認(rèn)適配的時(shí)候 將callbackExecutor作為一個(gè)參數(shù)傳進(jìn)去了。
static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;
    ...
    @Override
    public void enqueue(final Callback<T> callback) {

      delegate.enqueue(
          new Callback<T>() {
            @Override
            public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(
                  () -> {
                    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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
            }
          });
    }

callbackExecutor 是一個(gè)線程調(diào)度器。在這里執(zhí)行了一個(gè)異步操作delegate.enqueue.,在默認(rèn)初始化中callbackExecutor = platform.defaultCallbackexcetuor().他其實(shí)內(nèi)部調(diào)用的就是一個(gè) new MainThreadExecutor(). handler.post(s) 內(nèi)部使用使用Handler將響應(yīng)拋到了主線程中去。這就是子線程切換到主線程的核心方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Retrofit2作為目前最火的網(wǎng)絡(luò)請(qǐng)求框架之一,它是一個(gè)由Square組織開(kāi)發(fā)的可以在Android和java中...
    maoqitian閱讀 742評(píng)論 0 1
  • android中Retrofit源碼解析(新版) 在android開(kāi)發(fā)中我們?cè)鷳?yīng)用發(fā)起網(wǎng)絡(luò)請(qǐng)求的時(shí)候,不免需要使...
    CharlesCT閱讀 2,112評(píng)論 0 6
  • 一、什么是Retrofit A type-safe HTTP client for Android and Jav...
    andcoder閱讀 857評(píng)論 2 3
  • 說(shuō)明:本文的源碼分析較為粗淺,和其他源碼“解析”的文章相比并未特別詳細(xì),個(gè)人覺(jué)得看別人的源碼,將整體的思路和大框架...
    玉圣閱讀 650評(píng)論 0 0
  • 項(xiàng)目中的Retrofit是retrofit-2.0.0版本,我將項(xiàng)目中的版本和目前最新的Retrofit做對(duì)比進(jìn)行...
    cherishyan閱讀 386評(píng)論 0 0

友情鏈接更多精彩內(nèi)容