Retrofit2源碼解析(一)

Retrofit2源碼解析系列

本文基於Retrofit2的2.4.0版本php

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
複製代碼

Retrofit2底層基於OkHttp3,是對利用OkHttp3請求網絡的一種封裝,可使咱們避免寫不少重複的調用網絡請求的代碼,同時靈活性很高,能夠定製自定義的OkHttpClient、自定義的數據解析轉換器(好比Gson、Jackson等)、自定義的請求轉換器(好比結合RxJava)。java

Retrofit2的另外一個特色就是使用運行時註解,咱們在使用時能夠根據須要來利用註解將咱們的業務調用接口轉換成Http請求的接口。android

下面先來看看咱們使用Retrofit2發起網絡請求的步驟bash

(1)建立咱們的具體業務接口,這裏好比咱們調用淘寶的IP地址庫微信

public interface MyService {
    @GET("getIpInfo.php=11.11.11.11")
    Call<IpBean> getData();
}

複製代碼

(2)建立Retrofit網絡

retrofit = new Retrofit.Builder()
    .baseUrl("https://ip.taobao.com/service/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();
複製代碼

可見Retrofit2採用的是Builder模式來構建的ide

(3)利用Retrofit建立咱們的接口對象,生成Call對象,並調用請求網絡方法oop

MyService myService = retrofit.create(MyService.class);
Call<IpBean> call = myService.getData();
call.enqueue(new Callback<IpBean>() {
    @Override
    public void onResponse(Call<IpBean> call, Response<IpBean> response) {
        
    }

    @Override
    public void onFailure(Call<IpBean> call, Throwable t) {
        
    }
});
複製代碼

Retrofit的建立

首先咱們看看建立Retrofit時都作了哪些工做post

public Retrofit build() {
    //這裏能夠看出咱們必需設置baseUrl
    if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
    }
    
    //若是咱們沒有設置自定義的OkHttpClient,就用默認的OkHttpClient
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) {
        callFactory = new OkHttpClient();
    }
    
    //這個callbackExecutor用於回調到UI線程
    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
    }

    //將咱們設置的Call適配器添加到列表中,好比RxJava的適配器
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    //添加默認的Call適配器
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

    // Make a defensive copy of the converters.
    List<Converter.Factory> converterFactories =
            new ArrayList<>(1 + this.converterFactories.size());

    //添加數據轉換器,用於將網絡請求返回的結果轉換成咱們須要的類型
    converterFactories.add(new BuiltInConverters());
    converterFactories.addAll(this.converterFactories);
    
    //構建Retrofit
    return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
            unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
複製代碼

經過上面Retrofit2的Builder的build方法,咱們能夠看出在Retrofit2中主要有這麼幾個部分:ui

(1)用於執行具體網絡請求的callFactory,也就是OkHttpClient。因此說Retrofit2是基於OkHttp3的封裝。

(2)callbackExecutor回調執行器,這個是用於網絡請求返回後回調到主線程的。咱們知道,在利用OkHttp3進行網絡請求時,咱們須要手動回調到主線程,以便更新UI。那咱們來看看這個默認的defaultCallbackExecutor是否是這樣。

//Retrofit.class
public Builder() {
    this(Platform.get());
}

Builder(Platform platform) {
    this.platform = platform;
}
複製代碼

能夠看到在Builder中調用的是Platform的get方法,返回對應的平臺,而後在build方法裏經過platform的defaultCallbackExecutor獲得咱們的回調器。下面咱們看看這個Platform類

class Platform {
    private static final Platform PLATFORM = findPlatform();

    static Platform get() {
        return PLATFORM;
    }

    private static Platform findPlatform() {
        try {
            Class.forName("android.os.Build");
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
        }
        try {
            Class.forName("java.util.Optional");
            return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
    }
    
    ...
    
    static class Android extends Platform {
        @Override
        public Executor defaultCallbackExecutor() {
            return new MainThreadExecutor();
        }

        @Override
        CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
            if (callbackExecutor == null) throw new AssertionError();
            return new ExecutorCallAdapterFactory(callbackExecutor);
        }

        static class MainThreadExecutor implements Executor {
            private final Handler handler = new Handler(Looper.getMainLooper());

            @Override
            public void execute(Runnable r) {
                handler.post(r);
            }
        }
    }
}
複製代碼

從上面的源碼中咱們能夠看到Platform中會根據當前運行的平臺返回不一樣的子類,這裏固然就是Android這個內部類了。因此當咱們調用platform的defaultCallbackExecutor時,實際上調用的是Android這個類的defaultCallbackExecutor方法,而這個方法返回的是MainThreadExecutor,它的做用就是利用handler將執行結果回調到主線程中。

(3)callAdapterFactories適配器列表,這裏面存放的是全部的Call適配器CallAdapter。這個CallAdapter是幹嗎的呢?咱們知道Retrofit2底層是用Okhttp3來請求網絡的,那勢必是經過OkHttp3的Call來執行請求,可是咱們在實際使用Retrofit2時,可能須要結合請他的三方庫,常見的好比RxJava,那咱們接口中所須要返回的可能就是Observable而不是Call了。

@GET("getIpInfo.php?ip=11.11.11.11")
Observable<IpBean> getObservableData();
複製代碼

因此Retrofit2就須要一個Call適配器CallAdapter,來將Call轉換爲咱們須要的Observable,這就是CallAdapter的做用。

(4)converterFactories返回結果轉換器列表,這裏面存放的是將網絡返回結果,也就是OkHttp3返回的Response,解析轉換成咱們須要的實際類型,好比IpBean實體類。如GsonConverterFactory就是一個經常使用的轉換器,至關於Retrofit2把咱們直接使用Okhttp3來請求網絡數據時須要將返回結果進行Gson解析的動做也替咱們作了。

總結

(1)這裏咱們簡單分析了Retrofit的建立過程,能夠發現Retrofit中核心部分包括OkHttpClient、Call適配器、Response轉換器以及用於將請求回調到UI線程的回調執行器等。

(2)Retrofit的建立採用的是Builder模式,定製化程度很高,咱們能夠設置本身的OkHttpClient,也能夠實現自定義的Call適配器和Response轉換器,以及請求的回調執行器。

(3)可見Retrofit雖然作了很大程度的封裝,可是靈活性擴展性依然很高,咱們幾乎能夠擴展更改網絡請求的大部分過程。

今天咱們先淺嘗則止,後面咱們再來具體分析下Retrofit2的網絡調用過程,看看Retrofit2是怎麼利用適配器模式來爲咱們提供強大的靈活性的,敬請期待。


歡迎關注個人微信公衆號,和我一塊兒天天進步一點點!
複製代碼

AntDream
相關文章
相關標籤/搜索