Retrofit淺析

整體結構

Retrofit通過動態代理的方式,將我們聲明的interface轉換成一個請求,
通過靜態代理,將我們去請求交給okhttpclient去執行。

使用方法

 Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl("https://github.com/");
        builder.addConverterFactory(GsonConverterFactory.create());
        builder.addConverterFactory(GsonConverterFactory.create());
        Retrofit build = builder.build();
        GitInterfae gitInterfae = build.create(GitInterfae.class);
        Call<List<String>> azewz = gitInterfae.listRepos("azewz");
        azewz.enqueue(new Callback<List<String>>() {
            @Override
            public void onResponse(Call<List<String>> call, Response<List<String>> response) {
                Log.i("TAG","請求成功");
            }

            @Override
            public void onFailure(Call<List<String>> call, Throwable t) {
                Log.i("TAG", "請求失敗");
            }
        });
  1. 構件Buidler
    1. 確定平臺

    2. Builder初始化一個內建的Converters

  2. 設定baseURL
  3. build.create(API.class); 構件一個OkHttp中call的靜態代理
  4. 執行Call的實例,實際是調用OkHttp的call類
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, 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);
            }
            ServiceMethod serviceMethod = loadServiceMethod(method);
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }
  1. 當 Call<List<String>> azewz = gitInterfae.listRepos("azewz");就會執行動態代理中的handler的invoke,進行執行。
    loadServiceMethod將接口中聲明的方法轉換成我們一個ServiceMethod實例,包含了CallAdapter,RespenseConvert和請求的所有信息,例如http的頭信息,參數信息等。這里會有一
    個緩存,當改方法已經被實例化成ServiceMethod,將可以直接重緩存mapserviceMethodCache中取出。
    OKHttpCall就是okhttp的靜態代理類。
    當執行enqueue時,才發起請求。
  2. 當請求結果完成后,在OkHttpCall,使用parseResponse()解析返回的數據
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) { //請求成功,但是是沒有數據的
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
    try {
      T body = serviceMethod.toResponse(catchingBody); //調用我們的Convert類的轉換方法,
      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;
    }
  }

204 No Content
服務器成功處理了請求,但不需要返回任何實體內容,并且希望返回更新了的元信息。響應可能通過實體頭部的形式,返回新的或更新后的元信息。如果存在這些頭部信息,則應當與所請求的變量相呼應。
如果客戶端是瀏覽器的話,那么用戶瀏覽器應保留發送了該請求的頁面,而不產生任何文檔視圖上的變化,即使按照規范新的或更新后的元信息應當被應用到用戶瀏覽器活動視圖中的文檔。
由于204響應被禁止包含任何消息體,因此它始終以消息頭后的第一個空行結尾。
205 Reset Content
服務器成功處理了請求,且沒有返回任何內容。但是與204響應不同,返回此狀態碼的響應要求請求者重置文檔視圖。該響應主要是被用于接受用戶輸入后,立即重置表單,以便用戶能夠輕松地開始另一次輸入。
與204響應一樣,該響應也被禁止包含任何消息體,且以消息頭后的第一個空行結束。

自定義Convert

繼承 extends Converter.Factory
final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T>
final class JacksonRequestBodyConverter<T> implements Converter<T, RequestBody>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 適配器模式上一篇文章我們已經分析了Retrofit解析注解封裝進ServiceMethod的流程,讀者在這里要記住...
    andcoder閱讀 689評論 0 2
  • Retrofit的理解 實現了將網絡請求轉換成了調用一個java方法一樣那么簡單,在方法的回調里面解析響應。過程利...
    自然like閱讀 274評論 0 1
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • Retrofit這個開源庫出來也有一定年頭了,記得之前還是在V1.0的版本的時候,之前在三月份也寫過一個Retro...
    lovejjfg閱讀 1,471評論 0 5
  • 整體Retrofit內容如下: 1、Retrofit解析1之前哨站——理解RESTful 2、Retrofit解析...
    隔壁老李頭閱讀 4,028評論 1 3