前言
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.jianshu.com/")
//设置转换工厂
.addConverterFactory(GsonConverterFactory.create())
//设置适配器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
这里之所以叫Retrofit客户端。客户端提供的子系统有:
1.serviceMethodCache(自定义的接口映射对象集合)
2.baseUrl(请求地址)
3.callFactory(默认为OkHttpCall)
4.converterFactories(数据解析器工厂集合)
5.callAdapterFactories(Call适配器工厂集合)
6.callbackExecutor(回调执行,android平台默认为MainThreadExecutor)
关于Retrofit客户端的创建
客户端的创建有两种方式:
第一种就是使用构造函数,如下所示。
第二种就是Retrofit.Builder()。
我们一般使用第二种方式来创建客户端。
public final class Retrofit {
//对网络请求接口中方法注解进行解析后得到的对象,缓存到map中
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//网络请求器工厂
final okhttp3.Call.Factory callFactory;
//网络请求适配器器工厂集合
final List<CallAdapter.Factory> callAdapterFactories;
//数据转换器工厂集合
final List<Converter.Factory> converterFactories;
//回调方法执行器
final @Nullable Executor callbackExecutor;
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
}
接下来看看通过构建者模式创造的Retrofit客户端,使用构建者模式,有如下好处,对外可以屏蔽创建对象的细节,同时也可以自由配置Retrofit客户端的属性。
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
public Builder() {
this(Platform.get());
}
接着就到Platform.get()方法里
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
//安卓平台的platform
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
接着看看这个安卓平台的做了啥事
static class Android extends Platform {
@IgnoreJRERequirement // Guarded by API check.
@Override boolean isDefaultMethod(Method method) {
if (Build.VERSION.SDK_INT < 24) {
return false;
}
return method.isDefault();
}
@Override public Executor defaultCallbackExecutor() {
//返回一个默认的回调方法执行器,子线程请求后的数据通过这个来返回到主线程
return new MainThreadExecutor();
}
//默认的网络请求适配器工厂是ExecutorCallAdapterFactory ,常用的还有
//RxjavaCallAdapter,callAdapterFactory
@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
return Build.VERSION.SDK_INT >= 24
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
@Override int defaultCallAdapterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
}
//默认的转换器,常用的有GsonConverterFactory
@Override List<? extends Converter.Factory> defaultConverterFactories() {
return Build.VERSION.SDK_INT >= 24
? singletonList(OptionalConverterFactory.INSTANCE)
: Collections.<Converter.Factory>emptyList();
}
@Override int defaultConverterFactoriesSize() {
return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
可以看出这个Build类初始化了如下:
Platform:安卓平台对象
网络请求适配器工厂:CallAdapterFactory
数据转换器工厂:converterFactory
回调执行器:callbackExecutor
初始化数据转换器
addConverterFactory(GsonConverterFactory.creat())
先看看GsonConverterFactory.creat()里做了啥事
public final class GsonConverterFactory extends Converter.Factory {
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
//在自定义数据转化器时需重写这两个方法
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
这就是创建了一个还有Gson对象的GsonConverterFactory,并添加进converterFactorues中
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
由此看出
1.Retrofit默认使用Gson进行解析
2.若使用其他解析方式(如XML或Protocobuf),也可通过自定义数据解析器来实现(必须继承 Converter.Factory),重写那两个方法。
还有最后一个步骤,build(),Retrofit客户端就创建完成了。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//配置回调方法执行器
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// 配置网络请求适配器工厂
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// 配置数据转换器工厂
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
}
创建网络请求接口的实例
public interface Service{
@GET("wanandroid")
Call<Bean> getCall();
}
//使用了外观模式,通过传入class可以对每一个网络请求接口的访问
Service service = retrofit.create(Service.class);
Call<Bean> call = service.getCall();
Retrofit是通过动态代理模式创建网络接口的实例,同时,通过解析注解("wanandroid")进行了网络请求参数的配置
现在先来看接口的实例如何创建出来的
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
//这就是配置了那个数据转换器和网络适配器和回调池的platform
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@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);
}
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
}
});
}
接着看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;
}
接着去看parseAnnotations里做了啥事
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//这个就是去解析一些请求参数,比如说是否有请求体,请求方法是get post等等
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
//这里就是去解析注解信息带参数path的
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
最后就生成了一个serviceMethod对象。
接下来去分析一下这个serviceMethod
final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
//解析参数
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
Type responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError(method, "'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
throw methodError(method, "HEAD method must use Void as response type.");
}
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
}
//去遍历网络请求适配工厂
// //网络接口方法的返回值类型来确定合适的CallAdapter实例
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method) {
Type returnType = method.getGenericReturnType();
Annotation[] annotations = method.getAnnotations();
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
//去遍历数据转换器工厂
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
private final RequestFactory requestFactory;
private final okhttp3.Call.Factory callFactory;
private final CallAdapter<ResponseT, ReturnT> callAdapter;
private final Converter<ResponseBody, ResponseT> responseConverter;
private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
CallAdapter<ResponseT, ReturnT> callAdapter,
Converter<ResponseBody, ResponseT> responseConverter) {
this.requestFactory = requestFactory;
this.callFactory = callFactory;
this.callAdapter = callAdapter;
this.responseConverter = responseConverter;
}
//重点在这,生成serviceMethod对象时,会调用到invoke方法
@Override ReturnT invoke(Object[] args) {
return callAdapter.adapt(
new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
}
}
我们知道,Retrofit是对OkHttp做了一层封装,具体的网络发起人还是OkHttp,关键是怎么样通过这个serviceMethod来完成的呢?
先来看看构造函数,接收四个,第一个就是请求工厂,包含所有的请求参数,第二个就是网络接口的参数,第三个就是网络接口转换工厂,第四个就是数据转化工厂。
OkHttpCall(RequestFactory requestFactory, Object[] args,
okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactory;
this.responseConverter = responseConverter;
}
这里已经可以获取到我们所有网络请求发起需要的参数了。
接着去看看adapt,这就是网络接口请求返回类型的的适配,比如用的时RxjavaCallAdapter,返回的就是observerble。
网络请求的发起
最后的请求由OkhttpCall来发起。
public void enqueue(final Callback<T> callback) {
okhttp3.Call call;
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;
}
}
这个callBack就是在创建时客户端时那个ExtutorCallback。来完成线程的切换
总结
1.Retrofit将Http请求抽象成java接口
2.接口里用注解 描述和配置网络请求参数
3.动态代理的方式来生成call对象。
网友评论