简介
Retrofit采用一个java接口去发送一个http请求,请求参数以注解的形式写在java接口对应的方法中。关于Retrofit的使用,需要通过Builder构建一个Retrofit实例,然后产生一个接口的实现,例如:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyApi api = retrofit.create(MyApi.class);
api接口中的每个方法都要返回一个Call,通过这个Call可以execute或者enqueue一个Callback,即可得到相应结果
下面分别介绍Retrofit各个模块
注解
Retrofit提供的注解有很多种类,按注解的Target进行划分,有方法声明的注解,参数声明的注解等。
- 方法声明注解
PATCH
PUT
HEAD
Streaming
Multipart
DELETE
FormUrlEncoded
Headers
HTTP
GET
OPTIONS
POST
- 参数声明注解
Field
Part
PartMap
QueryMap
Body
HeaderMap
Url
QueryName
Header
Path
FieldMap
Query
这些注解的具体使用方法和注意事项,以后再单独说明
构造Retrofit:Builder
我们可以通过Retrofit.Builder得到一个Retrofit实例,在Builder中,可以对Retrofit进行各种配置,首先来看看Builder.builder()中都给了哪些配置,有哪些是可以自己配置的。
public Retrofit build() {
//配置基本的url
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//配置Factory
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
//
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
上面是Retrofit.Builder建立一个Retrofit的过程,从上面可以看出:
- baseUrl是必须要配置的,且不能为null,baseUrl是HttpUrl,Retrofit自己定义的一个类,可以通过下面接口进行配置:
// 1.直接配置HttpUrl
public Builder baseUrl(HttpUrl baseUrl) {
Utils.checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
//2.通过String进行配置
public Builder baseUrl(String baseUrl) {
Utils.checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
一般比较常用的是第二种配置方式,操作简单。
- 可以自己配置OkHttp的Factory,用于根据Request产生Call(调用newCall),默认是OkHttpClient。配置这个Factory也有两种方式:
//1.自定义OkHttpClient,这种方式可以对OkHttpClient进行一些额外的配置,比如添加拦截器
public Builder client(OkHttpClient client) {
return callFactory(Utils.checkNotNull(client, "client == null"));
}
//2.自定义一个Factory的实现
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = Utils.checkNotNull(factory, "factory == null");
return this;
}
- 自定义Execute,用于请求得到返回结果后执行,可以通过下面的方式进行配置:
public Builder callbackExecutor(Executor executor) {
this.callbackExecutor = Utils.checkNotNull(executor, "executor == null");
return this;
}
其默认值也配置好了,不过不同平台配置不同,其中Android平台的配置如下:
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
即,默认情况下是在主线程中执行
- 最后还要两个工厂集,分别是List
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(Utils.checkNotNull(factory, "factory == null"));
return this;
}
/** Add converter factory for serialization and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(Utils.checkNotNull(factory, "factory == null"));
return this;
}
其作用先放着,后面会进行说明
获取自定义接口实例:动态代理
只需要定义一个接口,然后把参数写上,就可以发送一个请求,那么真正的请求是怎么实现的呢?动态代理+注解。其动态代理的实现如下:
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() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//过滤掉Object属性的方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//Android平台这里是false,不用考虑
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.callAdapter.adapt(okHttpCall);
}
});
}
先分析下过程,其中具体细节先不考虑。上面通过loadServiceMethod得到一个ServiceMethod:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
在loadServiceMethod中有一个缓存:
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
即,一个method对应一个ServiceMethod。在我们定义的请求接口中,Method的注解是不会改变的,改变的是我们请求的参数,即参数注解。因此ServiceMethod是可以复用的。在建立ServiceMethod之后,会建立一个OkHttpCall,这里面传入了args,即参数注解中的值,这里返回的是:
return serviceMethod.callAdapter.adapt(okHttpCall);
这个返回值应该是一个Call,那么就顺着这个返回值,看看这个Call到底怎么实现的,首先要找到serviceMethod这里面的callAdapt是个什么东东。
在loadServiceMethod中,serviceMethod的创建是用的ServiceMethod.Builder:
result = new ServiceMethod.Builder<>(this, method).build();
在build的过程中:
callAdapter = createCallAdapter();
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//调用retrofit中的calladapt
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
最终这个adapt的实现还是在Retrofit中。继续跟踪:
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
Utils.checkNotNull(returnType, "returnType == null");
Utils.checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
这里有一个工厂:adapterFactories.get(i),通过这个工厂创建这个CallAdapt,这个工厂在哪呢?有两种:
1.在Retrofit.Builder中可以自己加入
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(Utils.checkNotNull(factory, "factory == null"));
return this;
}
2.默认生成
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
现在CallAdapter.Factory的作用体现出来了,用来产生CallAdapter的,一般在使用过程中,采用系统默认的实现比较多,系统的实现根据平台划分的,针对Android平台,
@Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
ExecutorCallAdapterFactory的get实现为:
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
终于找到源头了,最终的adapt返回的Call是ExecutorCallbackCall:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
得到这个Call,下一步应该干什么呢?请求,一个是execute,一个是enqueue,从代码中不难发现,ExecutorCallbackCall就像是一个代理,所有的工作都交给了传进来的那个Call,这个Call就是在Retrofit中传进来的OkHttpCall,那么就看看具体实现吧:
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
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 {
//创建OkHttp3.Call
call = rawCall = createRawCall();
} catch (Throwable t) {
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
//执行网络请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
t.printStackTrace();
}
}
private void callSuccess(Response<T> response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
这里创建了OkHttp3.Call,并且在OkHttp3.Callback中执行自己封装的Callback:
private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);// call factory就是okhttpclient
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
serviceMethod负责Request,这里又有一个工厂:serviceMethod.callFactory,它是OkHttp3.Call.Factory,即Retrofit中的OkHttpClient,这个可以自己定制,也可以是其默认值。到此,其封装到OkHttp就结束了。
以上只是对Retrofit的流程做了一个小小的总结,算是打开Retrofit大门的第一步吧,以后再对其逐步深入各个细节。