拆Retrofit2.0 的create()方法流程

滚滚长江东逝水,浪花也要乘风迎浪。一直在心里感激在网上写博客的各路大神们,在开发过程中帮助很大,自己也有心向先辈们学习,一来对自己也是一种督促,写博客也是巩固知识的过程,二来也希望能将自己开发中的所学记录下来,说不定能帮助到某些程序猿呢?这也是我的第一篇博客,内容如果有误还请指出来。好了,废话少说,进入正文。

Retrofit不用多介绍了,谁用谁知道。我在使用过程中会产生疑问:

1.声明的接口NetService怎么经过create就能调用发起网络请求?

2.接口中的方法可以返回Call,也可以返回其他类型,比如Observable,这之间有什么关系,或者经过怎样的转化过程?

带着这两个疑问去探索下create()方法的执行流程。下面是该方法的源码,比较短我们直接粘贴过来:

public  T create(final Class 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)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}

我们的第一个疑问有解了,在create中会通过Java动态代理的方式来处理对方法的调用问题。这样说可能比较抽象,简单举个栗子,通过动态代理就会返回Call对象。

public interface MyService{
@Get("info")
Call getUser();
}

重点是最后的三行代码。

1. ServiceMethod serviceMethod =(ServiceMethod)loadServiceMethod(method);

ServiceMethod官方解释:

Adapts an invocation of an interface method into an HTTP call

有四个重要的成员:

//封装call,默认是okHttpCall
this.callFactory = builder.retrofit.callFactory();
//最著名的RxJava,默认是不支持,通过添加.addCallAdapterFactory(RxJavaCallAdapterFactory.create())增加对Obsevable的支持
this.callAdapter = builder.callAdapter;
//addConverterFactory(GsonConverterFactory.create())将服务器返回的response,提取出ResponseBody(json)转化为User
this.responseConverter = builder.responseConverter;
// 负责解析API定义时每个方法的参数
this.parameterHandlers = builder.parameterHandlers;
2. okHttpCall = new OkHttpCall(serviceMethod, args);

OkHttpCall实现Call接口,主要会用到的方法execute和enqueue,一个同步一个异步。

@Override
public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}

可以看出,会通过createRawCall创建okhttp,创建过程先通过serviceMethod创建request,request传入callFactory创建okhttp3.Call。最后通过okhttpCall调用execute,enqueue的调用过程类似,最后也是通过okhttp调用enqueue。

private okhttp3.Call createRawCall() throws IOException {
Request request = serviceMethod.toRequest(args);
okhttp3.Call call = serviceMethod.callFactory.newCall(request);
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
3. serviceMethod.callAdapter.adapt(okHttpCall)

有几个概念需要注意下:

responseType:这个返回的是关注的类型,比如Call ,返回的是User的类型

returnType:这个是接口中方法的返回类型,比如Call那么返回的就是Call类型

public interface CallAdapter {
Type responseType();
T adapt(Call call);
public abstract CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit);
protected static Type getParameterUpperBound(int index, ParameterizedType type) {
return Utils.getParameterUpperBound(index, type);
}
protected static Class getRawType(Type type) {
return Utils.getRawType(type);
}
}

callAdapter是接口public interface CallAdapter的实现类

serviceMethod中的callAdapter通过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中根据returnType从adapterFactories(List adapterFactories = new ArrayList();)中得到callAdapter

    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);
if (adapter != null) {
return adapter;
}
}
…….
}

factories可以在初始化retrofit的时候添加,我们来看下默认的CallAdapter.Factory, 工厂模式,这个也是retrofit中大量使用的设计模式,在public interface Converter 接口中也会使用。DefaultCallAdapterFactory没有多少代码,重点看下get方法

1.默认的模式只支持Call这种returnType,所以一进来会判断是不是Call.class。

2.记下来会根据renturnType来获得responseType,也就是上面例子中Call中的User类型。

3.最后会new一个CallAdapter,因为默认的是支持Call这种returnType,因此在adapt方法中直接返回call。

    final class DefaultCallAdapterFactory extends CallAdapter.Factory {
static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();
@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 call;
}
} ;
}
}

4.我们再简单看看RxJava2CallAdapterFactory

    public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
......
@Override
public CallAdapter get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class rawType = getRawType(returnType);
......
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,isSingle, isMaybe, false);
}
}

在RxJava2CallAdapter中,看到熟悉的adapt方法,方法会将call封装成Observable,最后我们就可以快乐的使用RxJava

    final class RxJava2CallAdapter implements CallAdapter {
@Override
public Type responseType() {
return responseType;
}
@Override
public Object adapt(Call call) {
Observable > responseObservable = isAsync
? new CallEnqueueObservable(call)
: new CallExecuteObservable(call);
……
return observable;
}
}

当然还没完,我们在深入到Observable中一探究竟,我们看下异步CallEnqueueObservable的例子。可以看到实际执行还是通过call.enqueue(callback)执行。

    final class CallEnqueueObservable extends Observable {
private final Call originalCall;
CallEnqueueObservable(Call originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer>observer) {
// Since Call is a one-shot type, clone it for each new observer.
Call call = originalCall.clone();
CallCallback callback = new CallCallback(call, observer);
observer.onSubscribe(callback);
call.enqueue(callback);
}
private static final class CallCallback implements Disposable, Callback {
......
}
}

到这里我们对create()方法的分析过程就结束了,Retrofit是通过Java动态代理实现对接口方法的调用处理,通过解析方法的注解和参数封装request,通过request去构造HttpCall,再根据CallAdapter Factory对Call进行代理,其实内部还是通过OkHttp的Call模式做实际工作。Retrofit中比较多的使用工厂模式,实现很好的解耦,很值得借鉴。这方面的文章可以借鉴http://www.jianshu.com/p/45cb536be2f4。
谢谢!

扩展阅读:

https://blog.piasy.com/2016/06/25/Understand-Retrofit/

http://blog.csdn.net/lmj623565791/article/details/51304204

转自:http://www.jianshu.com/p/4d0eae0bc40c

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值