在 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<Bean>() {@Overridepublic void onResponse(Call<Bean> call, Response<Bean> response) {}@Overridepublic void onFailure(Call<Bean> call, Throwable t) { }});// 服务接口
interface INetService {Call<Bean> someThingCall();
}
这就是 Retrofit 的一个常规使用,先初始化,接着创建接口服务,接着就可以进行网络请求了,可以说比 Okhttp 简洁非常多。关键就是 Retrofit.create() 这个方法,里面做了非常多的事
package retrofit2;public final class Retrofit {public <T> T create(final Class<T> service) {validateServiceInterface(service); // 验证接口类return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] {service},new InvocationHandler() {@Overridepublic 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<T> {static <T> ServiceMethod<T> 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<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> 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<ResponseT, ReturnT> callAdapter =createCallAdapter(retrofit, method, adapterType, annotations); // 从 retrofit 中获取响应转换器Converter<ResponseBody, ResponseT> 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<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {@Overridefinal @Nullable ReturnT invoke(Object[] args) {// 创建能够进行网络请求的 CallCall<ResponseT> 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<T> implements Call<T> {final Executor callbackExecutor; // 这个是用来切换主线程的final Call<T> delegate; // 这个就是 OkHttpCallExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {this.callbackExecutor = callbackExecutor;this.delegate = delegate;}@Overridepublic void enqueue(final Callback<T> callback) { // 异步请求delegate.enqueue(new Callback<T>() {@Overridepublic void onResponse(Call<T> call, final Response<T> response) {callbackExecutor.execute(() -> {if (delegate.isCanceled()) {callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));} else {callback.onResponse(ExecutorCallbackCall.this, response);}});}@Overridepublic void onFailure(Call<T> call, final Throwable t) {callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));}});}@Overridepublic Response<T> execute() throws IOException { // 同步请求return delegate.execute();}}
}
总的来说,Retrofit是一个功能强大、易于使用的网络请求库,它简化了安卓应用程序与服务器之间的通信,提供了方便的接口定义和数据解析功能,是安卓开发中常用的网络请求工具之一。