1. 程式人生 > 其它 >Android開發—Retrofit2.9.0版本主流程分析

Android開發—Retrofit2.9.0版本主流程分析

簡介

Retrofit turns your HTTP API into a Java interface.

Retrofit將HTTP API轉換為Java介面

本文基於Retrofit2.9.0版本原始碼分析!

依賴新增:

com.squareup.retrofit2:retrofit:2.9.0

使用

我們在這以官網的Demo為例,來看下最簡單的使用:

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

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build(); ②

GitHubService service = retrofit.create(GitHubService.class); ③

Call<List<Repo>> repos = service.listRepos("octocat"); ④

repos.enqueue() ⑤

總體流程分為四步:

  1. 建立一個介面,內部方法都是介面呼叫的方法,使用註解的方式新增請求型別、引數和回撥資料等;
  2. 構建一個Retrofit物件,並且設定介面的baseUrl
  3. 使用retrofit.create(class)代理出一個我們第一步建立的介面例項;
  4. 使用介面例項執行具體的介面呼叫,返回Call物件;
  5. 使用call.enqueu()方法執行網路請求。

第一步不用具體分析,只需要知道如果使用註解來新增我們請求內容即可,具體如何解析這些註解會在第三步呈現出來,下面直接看第二步Retrofit的建立過程。

建立Retrofit

Retrofit.Builder().baseUrl(string)

retrofit2.Retrofit.Builder#baseUrl(java.lang.String)

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

public Builder baseUrl(HttpUrl baseUrl) {
  Objects.requireNonNull(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;
}

Retrofit.Builder().baseUrl(string)一共做了三個操作:

  1. 將傳入的url封裝成HttpUrl物件;
  2. 判斷url是否是以/結尾,不是的話直接丟擲異常;
  3. HttpUrl賦值給Builder.baseUrl

Builder.build()

retrofit2.Retrofit.Builder#build

public Retrofit build() {
    // baseUrl不能為空
    if (baseUrl == null) {
      throw new IllegalStateException("Base URL required.");
    } ①
    
    // 獲取平臺,Java/Android
    Platform platform = Platform.get(); ②

    // 建立OkHttpClient物件
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) {
      callFactory = new OkHttpClient();
    } ③

    // 建立回撥執行緒池物件
    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
      callbackExecutor = platform.defaultCallbackExecutor();
    } ④

    // 建立介面卡列表,並且新增預設的介面卡
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    List<? extends CallAdapter.Factory> defaultCallAdapterFactories =
        platform.createDefaultCallAdapterFactories(callbackExecutor);
    callAdapterFactories.addAll(defaultCallAdapterFactories); ⑤

    // 建立預設的轉換器列表
    List<? extends Converter.Factory> defaultConverterFactories =
        platform.createDefaultConverterFactories();
    int defaultConverterFactoriesSize = defaultConverterFactories.size();
    List<Converter.Factory> converterFactories =
        new ArrayList<>(1 + this.converterFactories.size() + 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(defaultConverterFactories); ⑥

    // 建立Retrofit物件
    return new Retrofit(
        callFactory,
        baseUrl,
        unmodifiableList(converterFactories),
        defaultConverterFactoriesSize,
        unmodifiableList(callAdapterFactories),
        defaultCallAdapterFactories.size(),
        callbackExecutor,
        validateEagerly); ⑦
  }
}

Builder.build()方法中主要就是建立或者獲取一些重要的物件,一共包括6個物件,下面一個個分析下具體作用:

  1. 第一步判斷baseUrl是否為空,為空直接拋異常;
  2. 第二步獲取Platform平臺物件,因為我們在Android工程中使用,所以獲取的是Android21或者Android24其中一個,Platform定義了回撥執行緒池、呼叫介面卡和轉換介面卡物件等;
  3. 第三步獲取回撥執行緒池物件,會從Platform物件中獲取預設的執行緒池;
  4. 第四步獲取CallAdapter.Factory列表,並且新增從Platform中獲取到的預設CallAdapter.Factory物件。CallAdapter的主要作用就是將我們介面返回的物件轉換成想要的型別,典型的就是RxJavaCallAdapter,它就是將預設的Call轉換成Observable
  5. 第五步獲取Converter.Factory列表,同時也會從Platform中獲取預設的Converter.Factory列表。Converter.Factory的主要作用就是將請求結果通過具體的操作轉換成想要的型別,典型的就是GsonConverter,它就是將String轉換成具體的資料類物件。
  6. 第六步建立Retrofit物件,然後設定上面獲取的物件。

Retrofit.cerate()

retrofit2.Retrofit#create

public <T> T create(final Class<T> service) {
  validateServiceInterface(service);
  return (T)
      Proxy.newProxyInstance( ①
          service.getClassLoader(),
          new Class<?>[] {service},
          new InvocationHandler() {
            private final Object[] emptyArgs = new Object[0];

            @Override
            public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                throws Throwable {
              // 判斷Service是介面還是類,如果是類直接呼叫類的方法
              if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
              }
              args = args != null ? args : emptyArgs;
              Platform platform = Platform.get();
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)
                  : loadServiceMethod(method).invoke(args); ②
            }
          });
}

Retrofit.create(class)方法中可以看出主要的有兩步:

  1. 第一步使用動態代理模式,根據傳入的class物件代理最終代理出一個例項;
  2. 第二步先判斷platform.isDefaultMethod(method),進入Android21類中此方法預設false,所以直接看loadServiceMethod(method)方法即可
    • loadServiceMethod(method)會建立一個ServiceMethod物件;
    • 再呼叫ServiceMethod.invoke(args)方法,這裡傳入的介面方法的引數

Retrofit.loadServiceMethod()

retrofit2.Retrofit#loadServiceMethod

ServiceMethod<?> loadServiceMethod(Method method) {
  // 檢視是否命中快取
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    // 加鎖並且雙重判斷是否命中快取
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 獲取新的ServiceMethod物件,並存入Map中
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

loadServiceMethod()方法內部邏輯還是比較簡單,先是從Map中獲取是否已經存在,不存在再加鎖去獲取新的ServiceMethod物件,最後放入快取Map中。具體的獲取流程還需要進入ServiceMethod.parseAnnotations(retrofit,method)方法中。

ServiceMethod.parseAnnotations()

retrofit2.ServiceMethod#parseAnnotations

static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  // 建立RequestFactory物件
  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);
  }
  // 返回型別不能為void型別
  if (returnType == void.class) {
    throw methodError(method, "Service methods cannot return void.");
  } ②
  // 建立HttpServiceMethod物件
  return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); ③
}

parseAnnotations()方法中主要做了三件事:

  1. 第一件就是建立了RequestFactory物件,這個接下來分析下這個物件作用是什麼;
  2. 第二件通過Method獲取方法返回值,並判斷可用性;
  3. 第三件轉到HttpServiceMethod中建立HttpServiceMethod物件,此類是ServiceMethod的子類。

RequestFactory.parseAnnotations(retrofit, method)

retrofit2.RequestFactory#parseAnnotations

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
  return new Builder(retrofit, method).build();
}

Builder(Retrofit retrofit, Method method) {
  this.retrofit = retrofit;
  this.method = method;
  this.methodAnnotations = method.getAnnotations();
  this.parameterTypes = method.getGenericParameterTypes();
  this.parameterAnnotationsArray = method.getParameterAnnotations();
}

RequestFactory build() {
  for (Annotation annotation : methodAnnotations) {
    parseMethodAnnotation(annotation); ①
  }
  // httpMethod不能為空,也就是設定的請求方式GET、POST等
  if (httpMethod == null) {
    throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
  } ②

  // 判斷請求提是否合規
  if (!hasBody) {
    if (isMultipart) {
      throw methodError(
          method,
          "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
    }
    if (isFormEncoded) {
      throw methodError(
          method,
          "FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
    }
  } ③

  int parameterCount = parameterAnnotationsArray.length;
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
    parameterHandlers[p] =
        parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
  } ④

  if (relativeUrl == null && !gotUrl) {
    throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
  }
  if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
    throw methodError(method, "Non-body HTTP method cannot contain @Body.");
  }
  if (isFormEncoded && !gotField) {
    throw methodError(method, "Form-encoded method must contain at least one @Field.");
  }
  if (isMultipart && !gotPart) {
    throw methodError(method, "Multipart method must contain at least one @Part.");
  }

  return new RequestFactory(this); ⑤
}

parseAnnotations()方法直接呼叫了內部Builder.build()方法,build()方法中,可以細分為五步:

  1. 第一步通過parseMethodAnnotation()解析方法上註解,解析的內容包括:請求方式、請求頭、請求地址、是否Multipart和是否FormUrlEncode等資訊,下面會詳細分析;
  2. 第二步判斷請求方式,如果為空直接拋異常;
  3. 第三步判斷MultipartFormUrlEncode註解,如果有請求體的時候,不可以有前面兩個註解,否則直接拋異常;
  4. 第四步通過parseParameter解析引數上註解,包括BodyFiledHeaderQuery等資訊;
  5. 第五步建立RequestFactory物件,將Builder傳入進去。

RequestFactory.parseMethodAnnotation()

retrofit2.RequestFactory.Builder#parseMethodAnnotation

private void parseMethodAnnotation(Annotation annotation) {
  if (annotation instanceof DELETE) {
    parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
  } else if (annotation instanceof GET) {
    parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
  } else if (annotation instanceof HEAD) {
    parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
  } else if (annotation instanceof PATCH) {
    parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
  } else if (annotation instanceof POST) {
    parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
  } else if (annotation instanceof PUT) {
    parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
  } else if (annotation instanceof OPTIONS) {
    parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
  } else if (annotation instanceof HTTP) {
    HTTP http = (HTTP) annotation;
    parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
  } else if (annotation instanceof retrofit2.http.Headers) {
    String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
    if (headersToParse.length == 0) {
      throw methodError(method, "@Headers annotation is empty.");
    }
    headers = parseHeaders(headersToParse);
  } else if (annotation instanceof Multipart) {
    if (isFormEncoded) {
      throw methodError(method, "Only one encoding annotation is allowed.");
    }
    isMultipart = true;
  } else if (annotation instanceof FormUrlEncoded) {
    if (isMultipart) {
      throw methodError(method, "Only one encoding annotation is allowed.");
    }
    isFormEncoded = true;
  }
}

parseMethodAnnotation()主要就是解析出方法上的註解,比如是GET還是POST請求,有沒有額外新增HEADER,或者是不是MultipartFormUrlEncoded

RequestFactory.parseParameter()

retrofit2.RequestFactory.Builder#parseParameter

private @Nullable ParameterHandler<?> parseParameter(
    int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
  ParameterHandler<?> result = null;
  if (annotations != null) {
    for (Annotation annotation : annotations) {
      ParameterHandler<?> annotationAction =
          parseParameterAnnotation(p, parameterType, annotations, annotation);

      if (annotationAction == null) {
        continue;
      }

      if (result != null) {
        throw parameterError(
            method, p, "Multiple Retrofit annotations found, only one allowed.");
      }

      result = annotationAction;
    }
  }
.....
  return result;
}

parseParameter()具體的解析流程在parseParameterAnnotation()方法中,由於此方法原始碼過於長,此處就不再貼原始碼了,裡面其實就是根據不同的註解型別來解析成對應的ParameterHandler物件。

具體的型別如下:

  • @Url註解,解析出來對應的是ParameterHandler.RelativeUrl()物件;
  • @Path註解,解析出來對應的是ParameterHandler.Path()物件;
  • @Query註解,解析出來對應的是ParameterHandler.Query()物件;
  • @QueryName註解,解析出來對應的是ParameterHandler.QueryName()物件;
  • @QueryMap註解,解析出來對應的是ParameterHandler.QueryMap()物件;
  • @Header註解,解析出來對應的是ParameterHandler.Header()物件;
  • @HeaderMap註解,解析出來對應的是ParameterHandler.HeaderMap()物件;
  • @Field註解,解析出來對應的是ParameterHandler.Field()物件;
  • @FieldMap註解,解析出來對應的是ParameterHandler.FieldMap()物件;
  • @Part註解,解析出來對應的是ParameterHandler.Part()物件;
  • @PartMap註解,解析出來對應的是ParameterHandler.PartMap()物件;
  • @Body註解,解析出來對應的是ParameterHandler.Body()物件;
  • @Tag註解,解析出來對應的是ParameterHandler.Tag()物件;

這就是所有的方法引數註解型別。

RequestFactory.parseAnnotations()分析完了之後回到HttpServiceMethod.parseAnnotations()

HttpServiceMethod.parseAnnotations()

retrofit2.HttpServiceMethod#parseAnnotations

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) {
  boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
  boolean continuationWantsResponse = false;
  boolean continuationBodyNullable = false;
  boolean continuationIsUnit = false;

  Annotation[] annotations = method.getAnnotations();
  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;
    } else {
      continuationIsUnit = Utils.isUnit(responseType);
    }

    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); ③
  Type responseType = callAdapter.responseType();
  if (responseType == okhttp3.Response.class) {
    throw methodError(
        method,
        "'"
            + getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
  }
  if (responseType == Response.class) {
    throw methodError(method, "Response must include generic type (e.g., Response<String>)");
  }
  // TODO support Unit for Kotlin?
  if (requestFactory.httpMethod.equals("HEAD")
      && !Void.class.equals(responseType)
      && !Utils.isUnit(responseType)) {
    throw methodError(method, "HEAD method must use Void or Unit as response type.");
  }

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

  okhttp3.Call.Factory callFactory = retrofit.callFactory; ⑤
  if (!isKotlinSuspendFunction) {
    return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  } else if (continuationWantsResponse) {
    //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForResponse<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter); ⑥
  } else {
    //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
    return (HttpServiceMethod<ResponseT, ReturnT>)
        new SuspendForBody<>(
            requestFactory,
            callFactory,
            responseConverter,
            (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
            continuationBodyNullable,
            continuationIsUnit); ⑦
  }
}

這裡面的邏輯還是略微比較多的,逐一看下:

  1. 第一步,判斷是否是Kotlin的掛起函式,然後通過getGenericParameterTypes獲取方法的返回型別;
  2. 第二步,如果不是Kotlin的掛起函式,直接通過getGenericReturnType獲取方法的返回型別,這裡的返回型別如果是泛型的話有可能拿不到具體的泛型值;
  3. 第三步建立CallAdapter,這裡假設我們沒有設定任何額外的CallAdapter,會使用預設的DefaultCallAdapter物件;
  4. 第四步建立ConverterAdapter,這裡我們一般使用Gson來解析響應結果,轉換成資料類,這邊假設使用的是GsonResponseBodyConverter物件;
  5. 第五步僅僅是獲取Retrofit物件中callFactory
  6. 第六步和第七步對Kotlin的掛起函式做判斷,分析過程中預設非掛起函式,直接進入第七步,煩惱會一個CallAdapted物件。

到這我們發現Retrofit.create()方法中,動態代理中loadServiceMethod()方法最終返回的就是CallAdapted物件,loadServiceMethod()方法後面直接呼叫了invoke()方法,接下來進入CallAdapted.invoke()方法。

CallAdapter.invoke()

進入CallAdapted物件中,發現並沒有invoke()方法的實現,只能退而求其次去看它的父類了:

retrofit2.HttpServiceMethod#invoke  

@Override
final @Nullable ReturnT invoke(Object[] args) {
  Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
  return adapt(call, args);
}

invoke()方法中首先建立了一個OkHttpCall物件,然後呼叫adapt()方法。

OkhttpCallRetrofit用來管理髮起網路呼叫和回撥的具體類。

CallAdapted.adapt()

retrofit2.HttpServiceMethod.CallAdapted#adapt

@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
  // 這裡的callAdapter為DefaultCallAdapterFactory中CallAdapter
  return callAdapter.adapt(call);
}

retrofit2.DefaultCallAdapterFactory#get

return new CallAdapter<Object, Call<?>>() {
  @Override
  public Type responseType() {
    return responseType;
  }

  @Override
  public Call<Object> adapt(Call<Object> call) {
    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
  }
};

adapt()方法直接呼叫callAdapter.adapt()方法,前面我們說到,預設使用CallAdapter,它是有DefaultCallAdapterFactory建立而成,CallAdapter.adapt()方法中只是建立了一個ExecutorCallbackCall物件。

到這裡我們就清除了,在使用章節第四步生成的Call其實就是ExecutorCallbackCall物件,讓他呼叫它的enqueue()方法就可以發起網路請求。

ExecutorCallbackCall.enqueue()

retrofit2.DefaultCallAdapterFactory.ExecutorCallbackCall#enqueue

ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
  this.callbackExecutor = callbackExecutor;
  this.delegate = delegate;
}

public void enqueue(final Callback<T> callback) {
  Objects.requireNonNull(callback, "callback == null");
  
  // 直接使用代理Call的enqueue方法,這裡的delegate就是OkHttpCall物件
  delegate.enqueue(
      new Callback<T>() {
        @Override
        public void onResponse(Call<T> call, final Response<T> response) {
          // 主執行緒中回撥結果,Android預設callbackExecutor為MainExecutor
          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));
        }
      });
}

ExecutorCallbackCall.enqueue()方法很簡單,直接呼叫delegate.enqueue(),然後將網路請求的結果回撥到主執行緒中去處理。

這裡的delegateCallAdapted.invoke()方法可以得知,它就是OkHttpCall物件,接著我們進入OkhttpCall.enqueue()方法。

OkHttpCall.enqueue()

retrofit2.OkHttpCall#enqueue

public void enqueue(final Callback<T> callback) {
  Objects.requireNonNull(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) {
          ...
        }

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

此方法才是最終呼叫Okhttp3發起網路請求最終地點,重要的一共有三步:

  1. 第一步檢查rawCall是否為空;
  2. 第二步如果rawCall為空,需要通過createRawCall()來建立OKhttp3.Call物件;
  3. 使用Okhttp3.Call.enqueue()方法來發起非同步請求。

到這為止,整個Retrofit網路請求流程就分析結束了,Retrofit並沒有執行任何網路請求操作,只是將所有方法註解、引數註解解析好之後,交給Okhttp3來發起具體的網路請求。

最後

為了幫助大家能夠更好地學習框架原始碼,特在此為大家分享一份阿里大佬整理的《Android百大框架原始碼解析》,這份資料有1880頁,乾貨十足。除了比較流行的Retrofit,OkHttp等,還收納了很多經典框架。雖然有些框架我們不再使用,但還是可以通過原始碼,來領略其中的精髓思想,為自己開闊思路。

適用讀者範圍:

  • 正在入門Android的新手——Android初級開發工程師 初出茅廬
  • Android初級開發工程師——中級開發工程師 知其然知其所以然
  • 中級、高階、資深工程師 知其然知其不可然

需要這份1880頁《Android百大框架原始碼解析》的朋友可以【點選這裡直達免費獲取方式!!!