Retrofit 使用介绍

Retrofit 使用介绍

Retrofit是利用注解声明的方法来调用Http请求的库

Retrofit.Builder()

设置url
必须以/结尾,否则会抛出异常

1
baseUrl()

可以用http://example.com来设置baseUrl,然后设置断点来覆盖这一条

设置是否提前验证Builder中的所有变量

1
validateEagerly(boolean validateEagerly)

添加转换工厂

1
addConverterFactory(Converter.Factory factory)

添加callAdapter

1
addCallAdapterFactory(CallAdapter.Factory factory)

添加执行回调

1
2
3
4
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = checkNotNull(executor, "executor == null");
return this;
}

执行回调是在调用后的Service之后的回调方法

Interface

必须是接口,不可以继承其他接口

1
2
3
4
interface ServiceAPI {
@GET("classify")
fun getHealthClassify(): Observable<List<HttpBean>>
}

代码解析

首先看下项目中的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var mService = getRetrofit().create(ServiceAPI::class.java)


private fun getRetrofit(): Retrofit {
return mRetrofit ?: Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.validateEagerly(true)
.client(OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor { chain ->
chain.proceed(chain.request()
.newBuilder()
// .addHeader()
.build())
}
.build())
.build()
}

create()

1
2
3
if (validateEagerly) {
eagerlyValidateMethods(service);
}

首先进行提前检查

1
private static final Platform PLATFORM = findPlatform();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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) {
}
try {
Class.forName("org.robovm.apple.foundation.NSObject");
return new IOS();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}

Android的platform里面有两个东西

  • 默认的handler
  • 如果没有设置,则创建默认的CallAdapter.Factory

这里会反射出此类中所有的方法,并将方法解析成一个ServiceMethod类中,最终加入到map里面

在解析构建的时候回执行一系列的检查,

  • 检查URL是否为空
  • 如返回值类型,是否是通配符,是否是元数据
  • 检查注解是否符合规则
  • 检查注解参数是否正确(多了少了)
  • 检查参数是否为空
  • 检查是否加入了注解
  • 检查动态URl是否为空

之后使用了反射+动态代理,在其中用classLoader加载在内存中的动态代理,来返回需要的返回类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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, @Nullable 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);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});

可以拿到Observable然后去订阅事件

时序图

创建时序

sequenceDiagram
    Retrofit-->callAdapterFactory:setCallAdapter()
    Retrofit-->>ServiceMethod:create()
    ServiceMethod-->>Retrofit:Build(),createCallAdapter()
    Retrofit-->>callAdapterFactory:setCallAdapter()
    callAdapterFactory-->>CallAdapter:()get
    ServiceMethod-->>responseConverter:createResponseConverter()
sequenceDiagram
    participant Alice
    participant Bob
    Alice->>John: Hello John, how are you?
    loop Healthcheck
        John->>John: Fight against hypochondria
    end
    Note right of John: Rational thoughts 
prevail... John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!
谢谢您的鼓励~