Retrofit做了什么

Retrofit 对 OkHttp进行了一层封装, 对网络层进行了解耦, 主要是通过注解,泛型,动态代理, 还有大量的设计模式来实现的.

Retrofit使用流程分析

  1. 构建一个Retrofit对象
1
2
3
4
5
6
7
8
9
val retrofit = Retrofit.Builder()

//Retrofit2的baseUrl 必须以 /(斜杆)结束,抛出一个IllegalArgumentException

.baseUrl("https://www.wanandroid.com/")

.addConverterFactory(GsonConverterFactory.create())

.build()

通过建造者模式构建对象可以灵活添加、修改功能如自定义OkHttpClient, 自定义转换器, 自定义适配器

  1. 通过Retrofit对象获取到api接口的代理对象
1
2
//2. 获取WanAndroidApi接口的代理对象
val wanAndroidApi = retrofit.create(WanAndroidApi::class.java)

​ 使用动态代理模式返回一个代理对象, 这里的Api需要提前定义好.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)throws Throwable {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);// Object的方法不属于接口, 直接调用
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);// 在这里去解析注解信息, 然后调用
}
});

  1. 通过代理对象去调用Api中提供的请求方法
1
2
//3. 获取具体的请求业务方法
val projectCall = wanAndroidApi.getProject()

​ 调用这个代理对象的方法时会调用到InvocationHandler中的invoke当中, 在里面会去调用loadServiceMethod方法去解析接口的注解参数得到一个ServiceMethod对象, 并将它保存存到ServiceMethodCahce当中, 以便下次调用的时候可以进行复用, 减少反射带来的开销. 然后接着去调用ServiceMethod的invoke方法, 返回一个Retrofit的Call对象, 里面包了一个真正的OkHttpCall对象和http请求参数以及一些适配器,转换器

  1. 发送一个同步/异步请求
1
2
3
4
5
6
7
8
9
10
11
12
//4. 发起请求
// 同步
// val projectBean = projectCall.execute()
//异步
projectCall.enqueue(object : Callback<ProjectBean> {
override fun onFailure(call: Call<ProjectBean>, t: Throwable) {
Log.i(TAG,"错误:${t.message}")
}
override fun onResponse(call: Call<ProjectBean>, response: Response<ProjectBean>) {
Log.i(TAG,"成功: ${response.body().toString()}")
}
})

这里可以传入一个接口回调, 默认配置情况下会使用DefaultCallAdapterFactory创建的Call, 也可以配合RxJava进行使用. 然后会调用到OkHttpCall的enqueue, 请求返回后OkHttp会去回调刚刚传入的接口回调

1
2
3
4
5
6
7
8
9
10
11
12
13
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
response = parseResponse(rawResponse);
...
callback.onResponse(OkHttpCall.this, response);
...
}

private void callFailure(Throwable e) {
...
callback.onFailure(OkHttpCall.this, e);
...
}

关键类分析

Retrofit
1.  serviceMethodCache(缓存的完整的调用, 对应一个url)
 2.  baseUrl (地址)
 3.  callFactory 
 4.  converterFactories(数据解析)
 5.  callAdapterFactories(适配器)
 6.  callbackExecutor
Platform(平台)

Platform使用恶汉式单例提供它的实例

如果是Dalvik虚拟机提供Android平台, 否则提供Java(8)平台

Call

Retrofit中定义的网络请求接口

OkHttpCall

OkHttp的Call实现, 可以通过getRawCall拿到okhttp3.Call对象

CallAdapter.Factory

calllAdapter静态工厂, 生产CalllAdapter对象

设计模式

  1. 建造者模式

    Retrofit, ServiceMethod对象的创建都用到了建造者模式, 简化了复杂对象的创建过程

  2. 外观模式

    Retrofit对外提供了统一的接口, 屏蔽了内部实现, 使用更加简单.

    简单的说就是通过提供一个高层接口去间接访问到子系统的不同接口, 类似一个接口整合的过程

  3. 动态代理模式

    通过生成一个代理对象, 并对代理对象进行监听, 当执行方法的时候自动回调到invocationHandler中.

  4. 静态代理模式

    Android平台默认使用DefaultCallbackFactory.ExecutorCallback, 具体实现delegate就是OkHttpCall

  5. 工厂模式

    Converter和CallAdapter的创建过程都是使用工厂模式来实现的

  6. 适配器模式

    看名字就知道CallAdapter.adapt使用了适配器模式, 可以对call进行动态扩展, 添加回调、观察者都可以