在 Android 开发中,Retrofit 是一个非常流行的网络请求库。它是由 Square 开发的,用于简化 Android 应用程序与网络服务器之间的通信。
Retrofit 主要用于处理 RESTful API 的网络请求。它通过将 HTTP 请求与 Java 接口方法进行映射,使得网络请求的编写变得简单和直观。使用 Retrofit,开发者可以定义一个描述网络请求的接口,然后通过注解将请求的URL、请求方法、请求参数等信息与接口方法绑定起来。Retrofit 会处理底层的网络请求和数据解析,开发者只需要关注业务逻辑的实现。
Retrofit 的使用:
// retrofit 初始化
retrofit = new Retrofit.Builder()
.baseUrl("https://www.wanandroid.com/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.build();
// 创建接口服务
INetService iNetService = retrofit.create(INetService.class);
// 进行网络请求
iNetService.someThingCall().enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
}
@Override
public void onFailure(Call call, Throwable t) { }
});
// 服务接口
interface INetService {
Call someThingCall();
}
这就是 Retrofit 的一个常规使用,先初始化,接着创建接口服务,接着就可以进行网络请求了,可以说比 Okhttp 简洁非常多。关键就是 Retrofit.create() 这个方法,里面做了非常多的事
package retrofit2;
public final class Retrofit {
public T create(final Class service) {
validateServiceInterface(service); // 验证接口类
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] {service},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// ....
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
}
可以看到,create 方法中使用了动态代理,返回的是 loadServiceMethod(method).invoke(args);
加载服务方法然后去执行,先看 loadServiceMethod:
ServiceMethod> loadServiceMethod(Method method) {
ServiceMethod> result = serviceMethodCache.get(method); // 先从缓存中取
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
会先从缓存中取,若没有缓存则调用 ServiceMethod.parseAnnotations():
package retrofit2;
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
// ... 对返回类型做判断
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
}
这个静态方法主要是对返回类型做判断,收集请求相关的信息、整理到 requestFactory 这个对象当中,再调用 HttpServiceMethod.parseAnnotations() :
package retrofit2;
abstract class HttpServiceMethod extends ServiceMethod {
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
// Kotlin 协程相关
} else {
adapterType = method.getGenericReturnType();
}
// 从 retrofit 中获取请求适配器
CallAdapter callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
// 从 retrofit 中获取响应转换器
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else {
// Kotlin 协程相关
}
}
}
最终,Retrofit.create() 方法中的 loadServiceMethod() 返回的是一个具有请求信息、okhttp 的请求工厂、响应转换器和请求适配器的 CallAdapted
接着,调用 loadServiceMethod().invoke():
package retrofit2;
abstract class HttpServiceMethod extends ServiceMethod {
@Override
final @Nullable ReturnT invoke(Object[] args) {
// 创建能够进行网络请求的 Call
Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
}
此时,会将之前的所有请求相关的参数,条件都封装到具有网络请求功能的 OkHttpCall,然后和请求参数一起适配到之前的适配器当中。
最终,返回的 Call 是 DefaultCallAdapterFactory.ExecutorCallbackCall:
package retrofit2;
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor; // 这个是用来切换主线程的
final Call delegate; // 这个就是 OkHttpCall
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override
public void enqueue(final Callback callback) { // 异步请求
delegate.enqueue(new Callback() {
@Override
public void onResponse(Call call, final Response response) {
callbackExecutor.execute(() -> {
if (delegate.isCanceled()) {
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override
public void onFailure(Call call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
@Override
public Response execute() throws IOException { // 同步请求
return delegate.execute();
}
}
}
总的来说,Retrofit是一个功能强大、易于使用的网络请求库,它简化了安卓应用程序与服务器之间的通信,提供了方便的接口定义和数据解析功能,是安卓开发中常用的网络请求工具之一。