中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Retrofit網絡請求和響應處理源碼分析

發布時間:2023-03-10 13:44:32 來源:億速云 閱讀:119 作者:iii 欄目:開發技術

本篇內容主要講解“Retrofit網絡請求和響應處理源碼分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Retrofit網絡請求和響應處理源碼分析”吧!

網絡請求

在使用 Retrofit 發起網絡請求時,我們可以通過定義一個接口并使用 Retrofit 的注解來描述這個接口中的請求,Retrofit 會自動生成一個實現該接口的代理對象。當我們調用這個代理對象的方法時,Retrofit 會根據注解的描述構建一個 Request 對象,并使用 OkHttp 將這個 Request 發送出去。

在 Retrofit 中,我們可以通過 Retrofit#executeRetrofit#enqueue 方法來發送請求。這兩個方法的區別在于,execute 方法會阻塞當前線程直到請求完成,而 enqueue 方法會將請求加入到 OkHttp 的請求隊列中,并在請求完成時通過回調通知我們。

我們先來看一下 execute 方法的實現:

public <T> T execute(Call<T> call) throws IOException {
  Utils.validateServiceInterface(call.request().tag(), call.request().url().toString());
  return (T) callAdapter(call, call.request().tag()).adapt(call).execute();
}

在這個方法中,首先會對接口進行校驗,確保這個接口是有效的。然后我們會根據請求的 Tag 和 URL 來獲取適配器callAdapter,并使用適配器來執行請求。

適配器的作用是將請求的參數適配成 OkHttp 能夠識別的形式,并將 OkHttp 的響應適配成我們需要的形式。Retrofit 提供了一系列的適配器,包括 Call 適配器、RxJava 適配器、CompletableFuture 適配器等。

我們來看一下 callAdapter 方法的實現:

private CallAdapter<?, ?> callAdapter(Call<?> call, Object tag) {
  Type responseType = call.request().method().equals("HEAD")
      ? Void.class
      : getParameterUpperBound(0, (ParameterizedType) call.request().tag());
  return callAdapter(tag, responseType);
}

在這個方法中,我們首先根據請求的方法來判斷響應的類型,如果是 HEAD 方法,那么響應的類型就是 Void;否則我們會通過反射來獲取請求的響應類型,并使用這個響應類型來獲取適配器。

獲取適配器的方法是 callAdapter

public <R, T> CallAdapter<R, T> callAdapter(Object tag, Type returnType) {
  // ...
  for (CallAdapter.Factory factory : adapterFactories) {
    CallAdapter<?, ?> adapter = factory.get(returnType, annotations, this);
    if (adapter != null) {
      return (CallAdapter<R, T>) adapter;
    }
  }
  // ...
}

在這個方法中,我們會遍歷所有的適配器工廠,嘗試獲取適配器。在獲取適配器時,我們會將請求的響應類型、注解和 Retrofit 實例作為參數傳入。每個適配器工廠都會判斷這些參數是否符合自己的適配條件,如果符合,就返回一個適配器實例,否則返回 null。在遍歷完所有的適配器工廠之后,如果還沒有獲取到適配器,那么就會拋出一個異常。

獲取到適配器之后,我們就可以使用適配器來執行請求了。在適配器中,我們會將請求參數轉換成 OkHttp 的 Request 對象,并將 OkHttp 的 Response 對象轉換成我們需要的響應類型。具體的實現可以參考 Retrofit 提供的 CallAdapter 接口。

對于 enqueue 方法,我們可以先來看一下 enqueue 方法的實現:

public <T> void enqueue(Call<T> call, Callback<T> callback) {
  Utils.validateServiceInterface(call.request().tag(), call.request().url().toString());
  callAdapter(call, call.request().tag()).adapt(call).enqueue(new CallbackRunnable<>(callback));
}

在這個方法中,我們首先進行接口校驗,然后根據請求的 Tag 和 URL 來獲取適配器,并使用適配器來執行請求。不同的是,在 enqueue 方法中,我們將一個 Callback 對象作為參數傳入適配器的 enqueue 方法中,以便在請求完成后回調通知我們。

在適配器中,我們可以看到 enqueue 方法的實現:

public void enqueue(final Callback<T> callback) {
  delegate.enqueue(new Callback<Response<T>>() {
    @Override public void onResponse(Call<Response<T>> call, Response<Response<T>> response) {
      Response<T> body;
      try {
        body = response.body();
      } catch (Throwable t) {
        if (response.code() == 204) {
          body = null;
        } else {
          callback.onFailure(call, t);
          return;
        }
      }
      if (response.isSuccessful()) {
        callback.onResponse(call, Response.success(body, response.raw()));
      } else {
        callback.onFailure(call, Response.error(response.errorBody(), response.raw()));
      }
    }
    @Override public void onFailure(Call<Response<T>> call, Throwable t) {
      callback.onFailure(call, t);
    }
  });
}

在這個方法中,我們會將傳入的 Callback 對象轉換成一個 Callback<Response<T>> 對象,并使用這個對象來調用 OkHttp 的 enqueue 方法。在請求完成后,我們會將 OkHttp 的 Response 對象轉換成 Retrofit 的 Response 對象,并根據響應碼來判斷請求的結果。如果響應碼表示請求成功,那么我們就調用 Callback 對象的 onResponse 方法;否則就調用 Callback 對象的 onFailure 方法。

響應處理

在 Retrofit 中,我們可以通過定義一個接口并使用注解來描述我們期望的請求格式和響應格式。例如,我們可以通過 @GET 注解來描述一個 GET 請求,使用 @Query 注解來描述請求參數,使用 @Body 注解來描述請求體,使用 @Headers 注解來描述請求頭等。

在執行請求時,Retrofit 會根據這些注解來自動生成一個對應的請求對象,并將請求對象轉換成 OkHttp 的 Request 對象。在接收響應時,Retrofit 會將 OkHttp 的 Response 對象轉換成一個對應的響應對象,并將響應對象中的數據轉換成我們需要的數據類型。這些轉換工作是通過 Retrofit 的轉換器來完成的,Retrofit 中默認提供了兩個轉換器:GsonConverterFactoryJacksonConverterFactory。我們也可以自定義一個轉換器來實現我們期望的數據轉換。

在 Retrofit 類的構造方法中,我們可以看到 Retrofit 默認使用了 Platform.get() 方法來獲取當前運行平臺的默認轉換器工廠,并將其添加到 converterFactories 中。然后,我們可以使用 addConverterFactory 方法來添加自定義的轉換器工廠。

public Retrofit(Builder builder) {
  // ...
  if (builder.converterFactories == null) {
    converterFactories.add(Platform.get().defaultConverterFactory());
  } else {
    converterFactories.addAll(builder.converterFactories);
  }
  // ...
}
public interface Platform {
  // ...
  Converter.Factory defaultConverterFactory();
}

execute方法中,我們會調用適配器的 adapt 方法來執行請求,并將返回的 Call 對象轉換成一個響應對象。在轉換過程中,我們會根據響應類型來選擇對應的轉換器來進行轉換。具體的轉換實現可以參考 Retrofit 提供的 Converter 接口和 Converter.Factory 接口。

public <T> T execute(Call<T> call) throws IOException {
  // ...
  Response<T> response = call.execute();
  if (response.isSuccessful()) {
    return response.body();
  } else {
    Converter<ResponseBody, ErrorResponse> converter = retrofit.responseBodyConverter(
        ErrorResponse.class, new Annotation[0]);
    throw new ApiException(converter.convert(response.errorBody()));
  }
}
@SuppressWarnings("unchecked") // Single-interface proxy creation guarded by parameter safety.
public <T> T adapt(Call<T> call) {
  return (T) new OkHttpCall<>(requestFactory, callFactory, converter, call);
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
  return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
    @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
  Objects.requireNonNull(type, "type == null");
  Objects.requireNonNull(annotations, "annotations == null");
  int start = converterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = converterFactories.size(); i < count; i++) {
    Converter<ResponseBody, ?> converter =
        converterFactories.get(i).responseBodyConverter(type, annotations, this);
    if (converter != null) {
      return (Converter<ResponseBody, T>) converter;
    }
  }
  throw new IllegalArgumentException(
      "Could not locate ResponseBody converter for " + type + " with annotations " + Arrays.toString(annotations));
}

以上是 Retrofit 中處理響應的核心代碼。當我們執行一個請求時,Retrofit 會先將請求轉換成 OkHttp 的 Request 對象并發送出去,然后等待響應返回。當響應返回時,Retrofit 會將響應轉換成一個響應對象,并將響應對象中的數據轉換成我們期望的數據類型。這個過程中,我們可以使用 Retrofit 提供的轉換器來自定義數據的轉換規則。

下面是一個示例,演示了如何使用 Retrofit 來發送一個 GET 請求并將響應中的 JSON 數據轉換成一個 Java 對象:

public interface ApiService {
  @GET("users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
ApiService apiService = retrofit.create(ApiService.class);
Call<List<Repo>> call = apiService.listRepos("smallmarker");
List<Repo> repos = call.execute().body();

在上面的示例中,我們首先使用 Retrofit 構建器創建一個 Retrofit 實例,并指定了請求的基礎 URL 和轉換器工廠。然后,我們通過調用 create 方法來創建一個 ApiService 的代理對象。最后,我們調用 listRepos 方法來發送一個 GET 請求。

在上面的示例中,我們使用了 Retrofit 的 GsonConverterFactory 來將響應體中的 JSON 數據轉換成 Java 對象。具體實現可以查看 Retrofit 提供的 GsonConverterFactory 類。

public final class GsonConverterFactory extends Converter.Factory {
  private final Gson gson;
  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }
  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);
  }
  @Override
  public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }
  @Override
  public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
                                                                  Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
}

可以看到,GsonConverterFactory 繼承了 Retrofit 的 Converter.Factory 類,并重寫了其中的 responseBodyConverter 方法和 requestBodyConverter 方法。在 responseBodyConverter 方法中,我們將響應體中的 JSON 數據轉換成 Java 對象,而在 requestBodyConverter 方法中,我們將 Java 對象轉換成請求體中的 JSON 數據。

除了 GsonConverterFactory 以外,Retrofit 還提供了其他的轉換器,如 JacksonConverterFactory、MoshiConverterFactory 等,我們可以根據需要選擇適合自己的轉換器。

總的來說,Retrofit 中網絡請求和響應處理的核心代碼非常簡潔明了。我們只需要通過定義接口來描述請求和響應,然后使用 Retrofit 的動態代理機制來將接口轉換成一個實際的實現類,并通過 Retrofit 的配置來指定請求和響應的轉換器即可。這種方式大大簡化了網絡請求的流程,使得我們可以更加專注于業務邏輯的處理。

到此,相信大家對“Retrofit網絡請求和響應處理源碼分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

牡丹江市| 广州市| 炉霍县| 洪雅县| 东丰县| 天等县| 黄山市| 开封县| 东至县| 德化县| 鸡泽县| 伊金霍洛旗| 西峡县| 福鼎市| 龙江县| 武威市| 姚安县| 天长市| 板桥市| 鹿邑县| 乐亭县| 天全县| 正镶白旗| 得荣县| 隆德县| 汨罗市| 衡水市| 南溪县| 南宫市| 定州市| 浑源县| 建昌县| 岱山县| 长兴县| 嘉善县| 宜兴市| 上高县| 阜城县| 体育| 收藏| 米脂县|