Retrofit 介紹、使用與原理解析

介紹

Retrofit是什么

retrofit:改進、翻新的意思。
Square 公司著名的開源項目之一。
Retrofit這個項目是一個 RESTful 的 HTTP 網(wǎng)絡請求框架的封裝。

為什么說它使網(wǎng)絡請求框架的封裝?
主要原因在于網(wǎng)絡請求的工作并不是 Retrofit 來完成的
Retrofit 2.0 開始內(nèi)置 OkHttp,前者專注于接口的封裝,后者專注于網(wǎng)絡請求的高效,二者分工協(xié)作。
我們的應用程序通過 Retrofit 請求網(wǎng)絡,實際上是使用 Retrofit 接口層封裝請求參數(shù)、Header、Url 等信息,之后由 OkHttp 完成后續(xù)的請求操作;在服務端返回數(shù)據(jù)之后,OkHttp 將原始的結(jié)果交給 Retrofit,后者根據(jù)用戶的需求對結(jié)果進行解析的過程。

所以說,所謂 Retrofit,其實就是 Retrofitting OkHttp 。

使用

看這里吧

原理解析

Retrofit這個框架的實現(xiàn)主要使用了哪些技術呢?
我覺得核心的就兩個:動態(tài)代理、注解

  • 動態(tài)代理
    動態(tài)代理可以理解成是雙層靜態(tài)代理,表面是A代理了B,其實是A將調(diào)用轉(zhuǎn)發(fā)給C,C再將調(diào)用轉(zhuǎn)發(fā)給B。
    開發(fā)者需要提供一個實現(xiàn)了InvocationHandler的子類 C。用戶直接調(diào)用代理類 A 的對象,A 將調(diào)用轉(zhuǎn)發(fā)給委托類 C,委托類 C 再將調(diào)用轉(zhuǎn)發(fā)給它的委托類 B。

舉個栗子

public class Main {
    public static void main(String[] args) {
        // create proxy instance
        TimingInvocationHandler timingInvocationHandler = new TimingInvocationHandler(new OperateImpl());
        Operate operate = (Operate)(Proxy.newProxyInstance(Operate.class.getClassLoader(), new Class[] {Operate.class},  timingInvocationHandler));
        // call method of proxy instance
        operate.operateMethod1();
        System.out.println();
        operate.operateMethod2();
        System.out.println();
        operate.operateMethod3();
    }
}

A:Porxy.newProxyInstance()生成的代理類
C:TimingInvocationHandler對象
B:OperateImpl對象

使用動態(tài)代理的關鍵就是中間的C,like this

public class TimingInvocationHandler implements InvocationHandler {

    private Object target;

    public TimingInvocationHandler() {}

    public TimingInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long start = System.currentTimeMillis();
        Object obj = method.invoke(target, args);
        System.out.println(method.getName() + " cost time is:" + (System.currentTimeMillis() - start));
        return obj;
    }
}

proxy:通過 Proxy.newProxyInstance() 生成的代理類對象
method:代理對象被調(diào)用的函數(shù)
args:表示代理對象被調(diào)用的函數(shù)的參數(shù)。

被代理的類(即委托類)以及相應的接口

public interface Operate {

    public void operateMethod1();

    public void operateMethod2();

    public void operateMethod3();
}

public class OperateImpl implements Operate {

    @Override
    public void operateMethod1() {
        System.out.println("Invoke operateMethod1");
        sleep(110);
    }

    @Override
    public void operateMethod2() {
        System.out.println("Invoke operateMethod2");
        sleep(120);
    }

    @Override
    public void operateMethod3() {
        System.out.println("Invoke operateMethod3");
        sleep(130);
    }

    private static void sleep(long millSeconds) {
        try {
            Thread.sleep(millSeconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
  • 注解
    不說了

好,現(xiàn)在進入正題,關于Retrofit的原理解析
Retrofit對象的create()方法,其內(nèi)部實現(xiàn)就是通過Porxy.newProxyInstance()來創(chuàng)建代理對象

作者:騰訊Bugly
鏈接:https://zhuanlan.zhihu.com/p/24109629
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

 public <T> T create(final Class<T> service) {
     Utils.validateServiceInterface(service);
     if (validateEagerly) {
       eagerlyValidateMethods(service);
     }
     //這里返回一個 service 的代理對象
     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);
             }
             //DefaultMethod 是 Java 8 的概念,是定義在 interface 當中的有實現(xiàn)的方法
             if (platform.isDefaultMethod(method)) {
               return platform.invokeDefaultMethod(method, service, proxy, args);
             }
             //每一個接口最終實例化成一個 ServiceMethod,并且會緩存
             ServiceMethod serviceMethod = loadServiceMethod(method);

             //由此可見 Retrofit 與 OkHttp 完全耦合,不可分割
             OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
             //下面這一句當中會發(fā)起請求,并解析服務端返回的結(jié)果
             return serviceMethod.callAdapter.adapt(okHttpCall);
           }
         });

之后,就可以在代理對象身上去調(diào)用的接口定義的那些方法了。
都知道,代理對象可以對原本委托對象的方法進行增強,附加更多的功能。
而對于Retrofit來講,代理對象就是給原本委托對象中相應的方法增加網(wǎng)絡請求獲取的功能,這個功能具體由誰來做呢,由OkHttp來做。

我們已經(jīng)看到 Retrofit 為我們構(gòu)造了一個 OkHttpCall ,實際上每一個 OkHttpCall 都對應于一個請求,它主要完成最基礎的網(wǎng)絡請求,而我們在接口的返回中看到的 Call 默認情況下就是 OkHttpCall 了,如果我們添加了自定義的 callAdapter,那么它就會將 OkHttp 適配成我們需要的返回值,并返回給我們。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容