概述
Retrofit 是一个用于 Android 和 Java 平台的类型安全的网络请求框架。Retrofit 是一个 RESTful 的 HTTP 网络请求框架的封装。 网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装,可以结合Rxjava、协程、以及LiveData使用。返回的序列化数据可以是 Gson、Jackson、Moshi、Protobuf等等
源码使用
创建以及使用
同样是Builder的模式创建的,可以指定BaseUrl,指定OkHttpClient,指定适配器,以及序列号工厂
- 创建Retrofit
Retrofit retrofit=new Retrofit.Builder()
.baseUrl(baseUrl)
.client(new OkHttpClient())
// 指定Rxjava适配器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
// 指定序列化结构
.addConverterFactory(GsonConverterFactory.create())
.build();
- 创建接口
public interface ApiService {
@GET("/wxarticle/list")
Call<ResponseBody> getNetData();
@GET("/wxarticle/list")
Observable<ResponseBody> getNetData2();
}
- 请求
// 创建 ApiService
ApiService apiService = retrofit.create(ApiService.class);
// 使用原始自带的请求
retrofit2.Call<NetData> netData = apiService.getNetData();
netData.enqueue(new retrofit2.Callback<NetData>() {
@Override
public void onResponse(retrofit2.Call<NetData> call, retrofit2.Response<NetData> response) {
}
@Override
public void onFailure(retrofit2.Call<NetData> call, Throwable t) {
}
});
// 适配成Rxjava流的请求
apiService.getNetData2()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(data -> {
}, error -> {
});
解析
创建retrofit的 Builder.Build方法
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
// 虽然这里用的工厂模式,但是 就new了一个OkHttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
// 因为在android中platform就是 Android,Platform中的一个内部类Android
callbackExecutor = platform.defaultCallbackExecutor();
}
// 这就是添加所有的adapter,这里用到的适配器模式,也就是从Okhttp的Call适配成Retrofit的Call
// 也可以添加咱们自己的适配器,比如RxJava2CallAdapterFactory.create(),Rxjava的。
// 还可以添加协程的 或者是LiveData的
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 这个是转化成javabean的转化类,有Gson 有 Moshi,有Protobuf,
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
// 执行 Retrofit 的构造方法
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
// 创建APIService,用的是动态代理的模式,在运行时创建了一个对象
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
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 {
// 如果是来自Object方法,继续走原来的逻辑
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
// 这个在Android中 isDefaultMethod()方法默认返回false。因为咱们就是用的接口中的方法
// 不会调用接口中的默认方法
//Java 8 引入了新的语言特性——默认方法(Default Methods
// 所以会走 loadServiceMethod(method).invoke(args)
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
// 返回一个ServiceMethod,执行里面的方法
ServiceMethod<?> loadServiceMethod(Method method) {
// 先从缓存中拿,有直接返回
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
// 因为用的反射,所以缓存一份
// 这里会返回 HttpServiceMethod ,ServiceMethod的一个子类
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
HttpServiceMethod:把Retorfit的注解参数以及Url 变成 Okhttp的Requst,有返回回来的Respone,还有在这里适配的请求,以及 适配成各种返回值,默认 Okhttp的Call 适配成 Retrofit的Call,或者 Rxjava 的 Observable,或者是协程,以及序列化 都是在这里转化的
看一下 请求,直接看默认的,不用看Rxjava的即可,看Retrofit的Call怎样转化到Okhttp的Call的
当我们执行的时候会走到 HttpServiceMethod中的invoke
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
// 是否是kotlin中的协程方法
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
// 得到所有的注解
Annotation[] annotations = method.getAnnotations();
// 获取返回类型
Type adapterType;
// 先不看 有关协程的,
if (isKotlinSuspendFunction) {
Type[] parameterTypes = method.getGenericParameterTypes();
Type responseType =
Utils.getParameterLowerBound(
0, (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
// Unwrap the actual body type from Response<T>.
responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
continuationWantsResponse = true;
} else {
}
adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
} else {
// 获取返回类型
adapterType = method.getGenericReturnType();
}
// 这里会走到Retrofit的nextCallAdapter方法,也就是从刚才咱们设置的Adapter的集合中遍历拿到 这个返回类型的
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
// 得到返回序列化类型,下面通过这个类型去找 序列化方法
Type responseType = callAdapter.responseType();
if (responseType == okhttp3.Response.class) {
}
if (responseType == Response.class) {
throw methodError(method, "Response must include generic type (e.g., Response<String>)");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
// 拿到 刚才设置的 converterFactories 集合,遍历拿到属于序列化方式
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
// 咱们先看这个不是协程的,CallAdapted 就是ResponseCallAdapter 或者是 RxJava2CallAdapter
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
}
}
刚才咱们也看到了OkHttpCall,这里面封装这Okhttp的Call。当我们调用请求的时候,实际就是调用的Okhttp的请求
final class OkHttpCall<T> implements Call<T> {
@Override
public void enqueue(final Callback<T> callback) {
Objects.requireNonNull(callback, "callback == null");
// 拿到Okhttp的call
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
// 默认使用的就是OkhttpClient的 new Call,上面说过,虽然用的是工厂,但是还是直接new的OkHttpClient
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
// 调用请求
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response<T> response;
try {
// 请求成功之后,来解析这个请求,返回真正的锁需要的
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace(); // TODO this is not great
}
}
});
}
}
// 解析返回值
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
try {
// responseConverter 就是默认的转化器,GsonRequestBodyConverter也可以,序列化成对应的格式
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}