介紹
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 適配成我們需要的返回值,并返回給我們。