Retrofit 2.0源码分析

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/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值