Retrofit源碼解讀(三)--RxJavaCallAdapterFactory講解

Retrofit源碼解讀(三)–RxJavaCallAdapterFactory講解

標籤(空格分隔):Retrofit源碼


前言

  • 以下的相關知識總結是通過慕課網的相關學習和自己的相關看法,如果有需要的可以去查看一下慕課網的相關教學,感覺還可以。

父類

which uses RxJava for creating observables

 final class RxJavaCallAdapterFactory extends CallAdapter.Factory

我們可以看到這個RxJavaCallAdapterFactory繼承的是Factory這個類,我們可以點進入可以看到Factory是CallAdapter這個接口的一個抽象類

Calladapter流程

就是把Retrofit裏面的Call這個泛型對象轉換成我們的java對象,通過這個java對象來進行數據轉換,UI顯示等等。。

Call<T> ---> Java對象

這裏的Retrofit裏面的Call不同於okhttp裏面的Call,這裏的是對於OkHttp的一個封裝,也就是說我們通過Retrofit來進行網絡請求,其實質就是通過OkHttp來進行的網絡請求,只不過Retrofit封裝了一層。

如何轉換成java對象

創建Call<T>對象,通過調用OkHttp請求,拿到服務器返回給我們的數據,這個時候通過我們的converter這個數據轉換器,把服務器給我們返回回來的response轉換爲我們需要的java對象,其中這個converter可以在我們創建retrofit實例的時候進行個性化的配置,比如addConverterFactory(GsonConverterFactory.create()) //設置數據解析器  默認使用的Gson

源碼分析


CallAdapter的成員變量
  • Type responseType();這個方法就是返回http請求返回後的類型,這個就是我們接口中的泛型的實參,比如如下:

    Returns the value type that this adapter uses when converting the HTTP response body to a Java

    • object. For example, the response type for {@code Call} is {@code Repo}. This type
    • is used to prepare the {@code call} passed to {@code #adapt}.
 @GET("article/list/latest?page=1")
    Call<HttpResult<List<TestBean>>> getQiuShiJsonString();
那麼這個Type就是HttpResult<List<TestBean>>這個實例
  • T adapt(Call call);
    這個就是返回的是Retrofit裏面的Call對象,如果是RxJava的話,那麼返回的就是一個 Observable
 Observable<BaseModel<ArrayList<PersonInfoBean.PersonalFood>>>

Factory內部抽象類

   這個就是根據我們的接口返回類型,註解類型得到我們實際需要的CallAdapter
   /**
     * Returns a call adapter for interface methods that return {@code returnType}, or null if it
     * cannot be handled by this factory.
     */
    public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);
  /**
     * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
     * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
     */
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }
獲取我們的原始的類型
 /**
     * Extract the raw class type from {@code type}. For example, the type representing
     * {@code List<? extends Runnable>} returns {@code List.class}.
     */
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }

RxJavaCallAdapterFactory代碼

1、繼承Factory

public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {

2、註冊CallAdapter

addCallAdapterFactory(RxJavaCallAdapterFactory.create())

3、調用Factory.get方法來獲取我們的CallAdapter

 @Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    //獲取到原始數據類型
    Class<?> rawType = getRawType(returnType);
    以下代碼省略
    / 。。。/

    //最終返回一個RxJavaCallAdapter  進行類型轉換
    return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
        false);
  }

4、調用adapt方法來講Call請求轉換

  @Override public Object adapt(Call<R> call) {

  //這個時候把retrofit的Call這個對象傳進來,這個然後通過
    OnSubscribe<Response<R>> callFunc = isAsync
        ? new CallEnqueueOnSubscribe<>(call)
        : new CallExecuteOnSubscribe<>(call);

    OnSubscribe<?> func;
    if (isResult) {
      func = new ResultOnSubscribe<>(callFunc);
    } else if (isBody) {
      func = new BodyOnSubscribe<>(callFunc);
    } else {
      func = callFunc;
    }
    // 通過Observable<?> observable 和Call創建關聯 可以看到func的創建和Call是有關聯的
    Observable<?> observable = Observable.create(func);
    //判斷調度器是否爲空
    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isSingle) {
      return observable.toSingle();
    }
    if (isCompletable) {
      return CompletableHelper.toCompletable(observable);
    }
    //直接返回observable
    return observable;
  }

總結

  • 理論:
    獲取到一個Call對象,拿到這個Call對象去執行http請求,而Retrofit調用這個Call請求,最終調用的還是okhttp裏面的Call請求,只不過對其進行了封裝,通過這樣我們就可以獲取到服務器端返回的數據,獲取到數據之後我們就會調用converter數據轉換器來把我們需要的對象轉換出來.

  • 實現:

    • 實現Factory這個抽象類
    • 註冊CallAdapter到retrofit中
    • 通過Factory.get方法獲取到具體的CallAdapter
    • 在調用adapt這個方法,最終轉換成每一個平臺適用的類型
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章