您的位置:首页 > 其它

Retrofit 2.0源码分析

2017-05-15 12:13 387 查看
Retrofit2.0是用注解的方式来描述一个HTTP请求,将HTTP请求抽象成一个Java的接口,然后用了Java动态代理的方式,将这个借口的注解“翻译”成一个HTTP请求,然后执行HTTP请求。

举例说明:

请求一个api: https://api.github.com/repos/{owner}/{repo}/contributors
查看github上某个repo的contributors.

首先你要这样建一个接口:
public interface GitHub {

@GET("/repos/{owner}/{repo}/contributors")
Call<List<Contributor>> contributors(@Path("owner")String owner,@Path("repo")String repo);
}
然后创建一个Retrofit
public static final String BASIC_URL="https://api.github.com";

Retrofit mRetrofit =new Retrofit.Builder().baseUrl(BASIC_URL).addConverterFactory
(GsonConverterFactory.create()).build();
创建一个GitHub
GitHub gitHub =mRetrofit.create(GitHub.class);
Call<List<Contributor>> call =gitHub.contributors("owner","repo");
最后回调获取数据
call.enqueue(new Callback<List<Contributor>>(){
@Override
public void onResponse(Response<List<Contributor>>respone){
for(Contributor controbutor: respone.body){

}
}

@Override
public void onFailure(Throwable t){

}
});

create方法重要就是返回了一个动态代理对象。(Java动态代理就是Java开发给了开发人员一种可能:当你要调用某个类的方法前,插入你想要执行的代码

比如你要执行某个操作前,你必须要判断这个用户是否登录,或者你在付款前,你需要判断这个人的账户中存在这么多钱。这么简单的一句话,我相信可以把一个不懂技术的人也讲明白Java动态代理是什么东西了。)

// Create an instance of our GitHub API interface.
GitHub github = retrofit.create(GitHub.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)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
return loadMethodHandler(method).invoke(args);
}
});


生成一个HTTP请求就是这句:Call<List<Contributor>> call = github.contributors("square", "retrofit");

github是一个动态代理对象,并不是一个真正的Githb接口的implements对象,当github对象调用contributors方法时
,Retrofit其实是执行了动态代理的InvocationHandler对象,最后会创建一个MethodHandler对象(Github接口翻译成一个HTTP请求,也就是MethodHandler对象),

这个对象中包含了4部分内容

static MethodHandler<?> create(Retrofit retrofit, Method method) {
CallAdapter<Object> callAdapter = (CallAdapter<Object>) createCallAdapter(method, retrofit);
Type responseType = callAdapter.responseType();
Converter<ResponseBody, Object> responseConverter =
(Converter<ResponseBody, Object>) createResponseConverter(method, retrofit, responseType);
RequestFactory requestFactory = RequestFactoryParser.parse(method, responseType, retrofit);

return new MethodHandler<>(retrofit.client(), requestFactory, callAdapter, responseConverter);
}
1. OkHttpClient:Retrofit默认生成的,发送网络请求的工具

2. RequestFactory: 类似于Volley中的Request,包含了HTTP请求的Url、Header信息,MediaType、Method以及RequestAction数组,通过RequestFactoryParser.parse(method, responseType, retrofit)生成,主要作用就是解析整个Http请求的所有数据,得到整个Http请求全部的信息,通过@Path和@Query注解拼接Url

3.  CallAdapter:HTTP请求返回数据的类型
private static CallAdapter<?> createCallAdapter(Method method, Retrofit retrofit) {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw Utils.methodError(method,
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw Utils.methodError(method, "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 Utils.methodError(e, method, "Unable to create call adapter for %s", returnType);
}
}
4. Converter:数据转换器,HTTP返回的数据解析成Java对象

 private static Converter<ResponseBody, ?> createResponseConverter(Method method,
Retrofit retrofit, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw Utils.methodError(e, method, "Unable to create converter for %s", responseType);
}
}


创建这4个对象的目的就是为了执行下面这句代码
Object invoke(Object... args) {
return callAdapter.adapt(new OkHttpCall<>(client, requestFactory, responseConverter, args));
}
这个也就是github.contributors("square", "retrofit")返回的Call对象

最后你调用Call对象的execute()或enqueue(Callback<T> callback)方法,就能发送一个Http请求了

Retrofit接口

1.这个接口就是retrofit请求数据返回的接口,只有两个方法

void onResponse(Response<T> response);

void onFailure(Throwable t);

2.Converter<F, T>

这个接口主要的作用就是将HTTP返回的数据解析成Java对象,主要由Xml、Gson、protobuf等等,你可以在创建Retrofit对象时添加你需要使用的Converter实现(看上面创建Retrofit对象的代码)

3.Call<T>

这个接口主要的作用就是发送一个HTTP请求,Retrofit默认的实现是OkHttpCall<T>,你可以根据实际情况实现你自己的Call类,这个设计和Volley的HttpStack接口设计的思想非常相似,子类可以实现基于HttpClient或HttpUrlConnetction的HTTP请求工具,这种设计非常的插件化,而且灵活

4.CallAdapter<T>
上面说到过,CallAdapter中属性只有responseType一个,还有一个<R> T adapt(Call<R> call)方法,这个接口的实现类也只有一个,DefaultCallAdapter。这个方法的主要作用就是将Call对象转换成另一个对象,可能是为了支持RxJava才设计这个类的吧。

===========================================》

文章转载:http://bxbxbai.github.io/2015/12/13/retrofit2/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Retrofit2.0