您的位置:首页 > 其它

retrofit2源码分析

2017-05-17 17:41 417 查看
如果对retrofit使用不太了解的可以去网上查一些资料,本篇就直接对源码进行分析了。

一、首先你需要RestfulApi 类,里面声明了咱们的请求

public interface RestfulApi {

// 获取时间戳
@POST("app.do?")
Call<T> getTime(@Query("pattern") String pattern);
}


然后封装Retrofit

public class HttpClient {
private RestfulApi apiService;
private OkHttpClient okHttpClient;

public HttpClient(Context context) {
okHttpClient = genericClient();
Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();

apiService = retrofit.create(RestfulApi.class);
}

// 创建OkHttpClient实例
private OkHttpClient genericClient() {
return new OkHttpClient.Builder().
addInterceptor(new HttpInterceptor())
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
}


然后调用异步接口就是

Call<T> call = apiService.getTime(pattern);
call.enqueue(callback);


二、下边针对retrofit2进行源码分析

// 创建OkHttpClient实例
private OkHttpClient genericClient() {
return new OkHttpClient.Builder().
addInterceptor(new HttpInterceptor())
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}


这一段代码很明显是对OkHttp中OkHttpClient的初始化,对OkHttp不了解可以看下

OkHttp3源码分析

Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();


这一段代码是对Retrofit的初始化

addConverterFactory(GsonConverterFactory.create())//对返回的数据支持json格式解析


client(okHttpClient)//设置okhttp3.Call.Factory callFactory = okHttpClient


最主要的就是下面这段代码

apiService = retrofit.create(RestfulApi.class);


查看源码

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 {
// 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)) {//Android/ios返回false,java8返回true
return platform.invokeDefaultMethod(method, service, proxy, args);
}
//组装ServiceMethod,里面有缓存,一样的方法只会执行一次,这个很大程度上优化了性能,因为反射是会消耗性能的
ServiceMethod serviceMethod = loadServiceMethod(method);
//传入的serviceMethod和参数
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}


发现上面是典型的Java动态代理

看上面的注释,Android中一定会走到下面,直接分析下面重要代码

ServiceMethod serviceMethod = loadServiceMethod(method);


ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);//从缓存中获取serviceMethod
if (result == null) {
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}


由于动态代理是用的反射的原理,然而所有的反射都有性能消耗,这里对method进行了缓存,每个方法只会运行一次

private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();


final修饰,引用地址不可变,这里用了LinkedHashMap表示不是很理解,LinkedHashMap底层是链表实现的,哪位朋友知道评论一下

//TODO


ServiceMethod里面的代码暂缓,等下再分析

OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);


看一下OkHttpCall的构造器

OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}


只是把刚声明的ServiceMethod和args参数传过去

serviceMethod.callAdapter.adapt(okHttpCall);


三、分析问题

1、serviceMethod.callAdapter是什么?

2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

先分析一下第一个问题

首先看ServiceMethod的build()里

public ServiceMethod build() {
callAdapter = createCallAdapter()


private CallAdapter<?> 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 {
return 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);
}
}


跑到了Retrofit类里

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}


public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
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);//ExecutorCallAdapterFactory   执行
if (adapter != null) {
return adapter;
}
}

StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append("  Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append("  Tried:");
for (int i = start, count = adapterFactories.size(); i < count; i++) {
builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}


最后走到了nextCallAdapter里,然后看只是从adapterFactories里取数据,看一下adapterFactories是什么

看一下Retrofit的build

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();
}

// 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);
}
}


重点看一下

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));


看一下Android的Platform

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);
}
}
}


callbackExecutor = platform.defaultCallbackExecutor() = new MainThreadExecutor();

由于MainThreadExecutor里的handler创建的Looper是主线程里的,so handler也是主线程(UI线程)里的,对Android的异步消息机制不了解的可以看下异步消息机制

看到没最后把UI线程赋值给了callbackExecutor

adapterFactories最后add的是ExecutorCallAdapterFactory

然后再回过头来

CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
//等同于
CallAdapter<?> adapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);


看一下ExecutorCallAdapterFactory类

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;//MainThreadExecutor 主线程

ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}

@Override
public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Call<?>>() {
@Override public Type responseType() {
return responseType;
}

@Override public <R> Call<R> adapt(Call<R> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}

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;//okhttpCall
}

@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();
}
}
}


回过头来看一下问题

1、serviceMethod.callAdapter是什么?

2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

答案:

serviceMethod.callAdapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);

callbackExecutor = MainThreadExecutor,这个是retrofit里传进来的

serviceMethod.callAdapter.adapt(okHttpCall) = ExecutorCallAdapterFactory.get(returnType, annotations, this).adapt(okHttpCall) = new ExecutorCallbackCall<>(callbackExecutor, okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall)

回过头来看一下我们业务层写的请求

Call<T> call = apiService.getTime(pattern);
call.enqueue(listener);


call = serviceMethod.callAdapter.adapt(okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall);

call.enqueue(callback) = ExecutorCallbackCall.enqueue(callback)

最后走到了OkHttpCall里,各位看官请看

delegate = OkHttpCall.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);
}
});
}
});


搞一段落,终于搞清楚了,最后代码会走到OkHttpCall.enqueue();

分析一下OkHttpCall.enqueue()

@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 {
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();
}
}
});
}


private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);//serviceMethod.callFactory是okhttpClient

if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}


ServiceMethod的builder

ServiceMethod(Builder<T> builder) {
this.callFactory = builder.retrofit.callFactory();


Retrofit里的

public Builder client(OkHttpClient client) {
return callFactory(checkNotNull(client, "client == null"));
}

/**
* Specify a custom call factory for creating {@link Call} instances.
* <p>
* Note: Calling {@link #client} automatically sets this value.
*/
public Builder callFactory(okhttp3.Call.Factory factory) {
this.callFactory = checkNotNull(factory, "factory == null");
return this;
}


这里面的逻辑其实就是走到了OkHttp里的RealCall.enqueue,然后再解析,回调。

对OkHttp不是很了解可以看下OkHttp源码分析

对源码逻辑明白了,但是想一想设计者为什么要这样设计retrofit,你会学到的更多。

retrofit的设计模式这篇文章写的特别好。

盗用一下图



真的是很美妙啊啊……..
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: