Retrofit源码详解

一.Retrofit代码详解

1.使用方式

Retrofit retrofit = new Retrofit.Builder().
                baseUrl("https://www.wanandroid.com/").
                addConverterFactory(GsonConverterFactory.create()).
                build();
        //1动态代理生成代理接口代理实例
        WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.class);
        //2创建Call
        Call<ProjectBeanResult> call=wanAndroidApi.getProject1();
        //3进行网络请求
        call.enqueue(new Callback<ProjectBeanResult>() {
            @Override
            public void onResponse(Call<ProjectBeanResult> call, Response<ProjectBeanResult> response) {
                Log.e("tag","当前的线程"+Thread.currentThread().getName());
                ProjectBeanResult projectBean = response.body();
                if(projectBean != null){
                    Log.e("tag","success "+projectBean);
                }
            }

​     @Override
​            public void onFailure(Call<ProjectBeanResult> call, Throwable t) {
​                Log.e("tag","onFailure...... ");
​            }
        });

​       代码分成重要的三步

(1)创建接口代理

 WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.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)
                //调用方法的时候,生成call对象
                        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);
                }
            });
}

(2)生成call对象 ,动态代理生成Call对象

Call<ProjectBeanResult> call=wanAndroidApi.getProject1();

//这时候动态代理使用下面的方法创建Call可以分为两部分1创建ServiceMethod2创建OkHttpCall

ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall);

①创建ServiceMethod

// ServiceMethod生成方式,缓存到Hashmap里面
ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
        result = serviceMethodCache.get(method);
        if (result == null) {
            result = new ServiceMethod.Builder(this, method).build();
            serviceMethodCache.put(method, result);
        }
    }
    return result;
}
然后看一下new ServiceMethod.Builder(this, method).build();方法
初始化1 callbackExecutor:回调执行器 2 CallAdapter 创建Call的适配器 3Converter 数据转换器4初始化请求参数,header信息
public ServiceMethod build() {
    callAdapter = createCallAdapter();
    responseType = callAdapter.responseType();
    if (responseType == Response.class || responseType == okhttp3.Response.class) {
        throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    responseConverter = createResponseConverter();
​
    for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
    }
​
    if (httpMethod == null) {
        throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
    }
​
    if (!hasBody) {
        if (isMultipart) {
            throw methodError(
                    "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
            throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
                    + "request body (e.g., @POST).");
        }
    }
​
    int parameterCount = parameterAnnotationsArray.length;
    parameterHandlers = new ParameterHandler<?>[parameterCount];
    for (int p = 0; p < parameterCount; p++) {
        Type parameterType = parameterTypes[p];
        if (Utils.hasUnresolvableType(parameterType)) {
            throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
                    parameterType);
        }
​
        Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
        if (parameterAnnotations == null) {
            throw parameterError(p, "No Retrofit annotation found.");
        }
​
        parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
    }
​
    if (relativeUrl == null && !gotUrl) {
        throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
    }
    if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError("Non-body HTTP method cannot contain @Body.");
    }
    if (isFormEncoded && !gotField) {
        throw methodError("Form-encoded method must contain at least one @Field.");
    }
    if (isMultipart && !gotPart) {
        throw methodError("Multipart method must contain at least one @Part.");
    }
​
    return new ServiceMethod<>(this);
}

②创建Call对象

//先创建一个Call OkHttpCall
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//然后通过适配器模式转一个下okhttpCall生成一个Call
        return serviceMethod.callAdapter.adapt(okHttpCall);
        
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
​
    @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 retrofit2.ExecutorCallAdapterFactory.ExecutorCallbackCall<>(callbackExecutor, call);
            }
        };
    }
}
​
}

(3)进行网络请求

call.enqueue(new Callback<ProjectBeanResult>());
    //调用的是ExecutorCallbackCall的enqueue
    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是OkhttpCall对象
            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(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, new IOException("Canceled"));
                            } else {
                                callback.onResponse(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, response);
                            }
                        }
                    });
                }
​
                @Override public void onFailure(Call<T> call, final Throwable t) {
                    callbackExecutor.execute(new Runnable() {
                        @Override public void run() {
                            callback.onFailure(ExecutorCallAdapterFactory.ExecutorCallbackCall.this, t);
                        }
                    });
                }
            });
        }
​
​
        }
    }
//OkHttpCall的enqueue 很简单就是分为两步1创建Okhttp的call2用Okhttp进行请求
@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 {
                //1创建okhttp的Call,
                call = rawCall = createRawCall();
            } catch (Throwable t) {
                failure = creationFailure = t;
            }
        }
    }
​
​
    if (canceled) {
        call.cancel();
    }
    //okhttp的Call请求网络
    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);
        }
​
​
    });
}
//创建okhttp  Call的过程,通过serviceMethod 生成Request,通过callFactory生成Okhttp的Call
//serviceMethod 就是干这个用的
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;
}

使用静态代理ExecutorCallbackCall(代理类)真实调用的是OkhttpCall的方法,okhttpCall方法执行完成之后,用回调的线程池执行回调操作

2.总结

先构建Retrofit对象,通过构造者模式构建,然后通过动态代理构建出来代理的接口,然后调用代理接口的请求方法生成Call,主要就是构造ServiceMethod对象,里面包含1 callbackExecutor:回调执行器 2 CallAdapter 创建Call的适配器 3Converter 数据转换器4初始化请求参数,header信息,然后通过ServiceMethod对象构造OkHttpCall的Call,然后通过这个call发送网络请求,请求过程先通过ServiceMethod(也就是应用新建接口生初始化的注释的的那些配置,通过这些生成请求的参数)生成Okhttp的call,然后发起网络请求,然后通过Converter数据解析器解析数据,然后切换到回调线程池里面回调执行方法

3.问题总结

(1)Retrofit如果将interface转成网络请求的?

通过动态代理,首先将接口里面的注释信息的参数解析出来,生成url,请求信息等参数封装到ServiceMethod里面,然后通过ServiceMethod对象构造出来Call请求

(2)Retrofit的Converter机制如何实现?

通过addConverterFactory(GsonConverterFactory.create())添加一个数据转换器

responseConverter = createResponseConverter();
private Converter<ResponseBody, T> createResponseConverter() {
  Annotation[] annotations = method.getAnnotations();
  try {
    return retrofit.responseBodyConverter(responseType, annotations);
  } catch (RuntimeException e) { // Wide exception range because factories are user code.
    throw methodError(e, "Unable to create converter for %s", responseType);
  }
}
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
  return nextResponseBodyConverter(null, type, annotations);
}
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,
    Type type, Annotation[] annotations) {
  checkNotNull(type, "type == null");
  checkNotNull(annotations, "annotations == null");
​
  int start = converterFactories.indexOf(skipPast) + 1;
  for (int i = start, count = converterFactories.size(); i < count; i++) {
    Converter<ResponseBody, ?> converter =
        converterFactories.get(i).responseBodyConverter(type, annotations, this);
        //如果这个转换器返回的不为空就是用这个
    if (converter != null) {
      //noinspection unchecked
      return (Converter<ResponseBody, T>) converter;
    }
  }

重要的方法是

Converter<ResponseBody, ?> converter = converterFactories.get(i).responseBodyConverter(type, annotations, this); //如果这个转换器返回的不为空就是用这个 if (converter != null) { //noinspection unchecked return (Converter<ResponseBody, T>) converter; }

判断注册的所有的ConverterFactores 能不是转化成Convert,是通过type这里type就是你接口的返回值ProjectBean.callss,判断能不能处理这个类,能处理就使用这个工厂创建的Convert

@GET("project/tree/json")
public Call<ProjectBean> getProject();
//默认的数据格式转换器的工厂,从代码看的出来返回值是ResponseBody才能处理。
final class BuiltInConverters extends Converter.Factory {
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    if (type == ResponseBody.class) {
      if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
        return StreamingResponseBodyConverter.INSTANCE;
      }
      return BufferingResponseBodyConverter.INSTANCE;
    }
    if (type == Void.class) {
      return VoidResponseBodyConverter.INSTANCE;
    }
    return null;
  }

遍历所有的自定义ConvertersFactory的list,然后判断每个Factory能处理ProjectBea.class(也就是接口返回的参数),来判断能不能使用这个转换器,不能就返回空,继续遍历下一个。

4.使用的设计模式

(1)建造者模式

Refrofit和ServiceMethod对象的创建,将对象的创建和表示(内部实现)分离,调用者不用知道复杂的创建过程

(2)外观模式

ServiceMethod的build方法,使用了多种对象的的方法,统一封装到build里面ServiceMethod是门面角色。

(3)动态代理

接口类的创建,根据接口类动态构建一个接口的实现类

WanAndroidApi wanAndroidApi=retrofit.create(WanAndroidApi.class);

(4)静态代理

call.enqueue(new Callback<ResponseBody>());
发起请求的时候,静态代理类是ExecutorCallAdapterFactory,真实使用的是OkhttpCall,然后执行完回调到静态代理类里面,切换到回调线程池操作

(5)工厂模式

Convert和CallAdapter的是实现

(6)适配器模式

CallAdapter生成Call的过程

//先创建一个Call OkHttpCall
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
//然后通过适配器模式转一个下okhttpCall生成一个Call
        return serviceMethod.callAdapter.adapt(okHttpCall);
​
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
​
    @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 retrofit2.ExecutorCallAdapterFactory.ExecutorCallbackCall<>(callbackExecutor, call);
            }
        };
    }
}
​
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值