注意:这篇文章不是一篇系统的文章,如果查看完整系统文章可以参考文末的相关文章。
这篇文章只对自己觉得重要的地方进行了分析。
使用方法:官方使用教程
主要有以下步骤:
1. 编写Api接口
2. 创建Retrofit实例
3. 获得ApiService
4. 获取请求
5. 执行请求(同步或者异步)
类似下面的代码:
//1.编写Api接口:
public interface GitHubService {
@GET("users/{user}/repos")
Call> listRepos(@Path("user") String user);
}
//2.创建Retrofit实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
//3.获得ApiService
GitHubService service = retrofit.create(GitHubService.class);
//4.获取请求
Call> repos = service.listRepos("octocat");
//5.执行请求
repos.enqueue(new Callback>()
{
@Override
public void onResponse(Call> call, Response> response)
{
}
@Override
public void onFailure(Call> call, Throwable t)
{
}
});
源码解析:
首先给出Retrofit类中非常重要成员变量的解释:
final okhttp3.Call.Factory callFactory; //okhttpClient,用于产生Call请求
final List converterFactories; //数据解析器,将ResponseBody和定义的数据类型进行转换
final List adapterFactories; //对Call进行转化,默认为 ExecutorCallbackCall
final @Nullable Executor callbackExecutor; // 请求返回的线程池
下面进行源码分析(基于上面提到的使用方式中的代码进行分析):
1. 跟踪Retrofit的创建
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
底层实现(Retrofit.class)
//采用Build模式,通过传入的参数构建实例
public Retrofit build() {
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
//所以可以看出callFactory其实是OkHttpClient,并且如果外部没有设定就自己new一个
callFactory = new OkHttpClient();
}
//请求返回的线程执行者
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
//添加的GsonConverterFactory.create()存储converterFactories里
List converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
}
GitHubService service = retrofit.create(GitHubService.class);
底层实现(Retrofit.class)
//使用动态代理的方式进行对象构造。
//之所以选择接口的形式,个人认为是因为比较简洁
public T create(final Class 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, @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);
}
//重要的地方。
ServiceMethod
接下来对下面代码进行分析:
//将apiService接口中的方法传入,生成ServiceMethod
1. ServiceMethod serviceMethod =
(ServiceMethod) loadServiceMethod(method);
//根据serviceMethod和args构建出Call.(类似Okhttp3中的请求Call)
2. OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//返回apiService中的返回类型对应的Call
3. return serviceMethod.callAdapter.adapt(okHttpCall);
特别说明
ServiceMethod:主要存储api接口中的所有请求参数。根据前面提到的动态代理技术以及注解,获取到一系列参数。
//从缓存中取,没有就新生成一个
ServiceMethod, ?> loadServiceMethod(Method method) {
ServiceMethod, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//使用Build模式生成一个ServiceMethod
result = new ServiceMethod.Builder<>(this, method).build();
//加入到Map集合
serviceMethodCache.put(method, result);
}
}
return result;
}
//构造函数
OkHttpCall(ServiceMethod serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
enqueue方法:
@Override public void enqueue(final Callback callback) {
...
}
//可见还是使用了Okhttp
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response 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 response) {
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
t.printStackTrace();
}
}
});
}
//默认的callAdapter其实是在Retroft的build()方法中传入
//的"platform.defaultCallAdapterFactory(callbackExecutor)",具体细节跟下源码
List.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
查看Platform
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
//走这个逻辑
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
ExecutorCallAdapterFactory:
对Call对象进行封装,回调时通过callbackExecutor进行回调到UI线程中去。也对应着Retrofit的回调在主线程
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
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>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
//将回调放在主线程中执行
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response 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 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 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 clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}
总结:
1. 使用动态代理和注解的技术,将api方法中的参数解析到ServiceMethod中去。
2. 内部封装okhttp,使用converterFactoriy将ResponseBody和对象,对象和RequestBody进行转换
3. 使用converterAdapter进行线程切换
下面给出一些文章地址:
Retrofit2 完全解析 探索与okhttp之间的关系
Retrofit2 源码解析