千家信息网

Retrofit源码的示例分析

发表于:2025-11-16 作者:千家信息网编辑
千家信息网最后更新 2025年11月16日,这篇文章主要介绍了Retrofit源码的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。基本使用介绍介绍源码前,我们先看下Ret
千家信息网最后更新 2025年11月16日Retrofit源码的示例分析

这篇文章主要介绍了Retrofit源码的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

基本使用介绍

介绍源码前,我们先看下Retrofit的基本使用,大致了解下流程,跟着这个流程来分析源码才不会乱。

1、初始化Retrofit对象

Retrofit retrofit = new Retrofit.Builder()    //使用自定义的mGsonConverterFactory    .addConverterFactory(GsonConverterFactory.create())    .baseUrl("http://apis.baidu.com/txapi/")    .build();

2、定义接口

public interface APi {  @GET("hello/world")  Call getNews(@Query("num") String num,@Query("page")String page);}

3、发起网络请求

mApi = retrofit.create(APi.class);Call news = mApi.getNews("1", "10");news.enqueue(new Callback() {  @Override  public void onResponse(Call call, Response response) {  }  @Override  public void onFailure(Call call, Throwable t) {  }});

Retrofit本质分析

看到上面的整个流程,不去探究源码的话肯定一脸懵逼,我就定义了一个接口,指定了下返回值,为毛这个接口就可以直接用了?接口的实现呢?我随便写一个返回值,不指定返回Call行不行?待着这些疑问,我们大致也可以猜出Retrofit是干什么的了。

猜测:Retrofit主要就是为我们定义的接口创造了一个实例,然后这个实例调用接口中的方法将我们定义在注解中的值拼装成发起http请求所要的信息,最后利用这些信息产生一个我们在接口返回值中规定的对象,这个对象可以用来发起真正的请求。
简单的讲,Retrofit就是把注解中的东西拼成http请求的对象,然后由这个对象去发起请求。

验证猜测

是谁实现了这个接口

发起网络请求时,有这样一句:

mApi = retrofit.create(APi.class);

很明显,接口的实现应该是这个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, @Nullable 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 =        (ServiceMethod) loadServiceMethod(method);      OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);      return serviceMethod.adapt(okHttpCall);     }    }); }

这里我们不用去看一些细节,只去关注我们想知道的,这个Create方法到底干了什么,看到Proxy.newProxyInstance,哦!这就很明显了,这里接口之所以能够直接调用是使用了动态代理技术,产生了一个代理对象。binggo,一个问题解决!!!

什么时候开始将注解中参数拼装成http请求的信息的?

动态代理是干什么的?(大家最好单独去学习下Java的动态代理,有时候非常有用,资料网上大把大把的)
使用动态代理一般是为了拦截方法,好在个方法执行的时候,在执行之前或之后干些自己的事情。这里回顾下Retrofit的使用,通过Create方法产生代理对象后直接就调用定义的方法了。那么,所有的小动作必然是在调用接口方法的时候干的。具体就是invoke中的方法

  if (method.getDeclaringClass() == Object.class) {       return method.invoke(this, args);      }      if (platform.isDefaultMethod(method)) {       return platform.invokeDefaultMethod(method, service, proxy, args);      }      ServiceMethod serviceMethod =        (ServiceMethod) loadServiceMethod(method);      OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);      return serviceMethod.adapt(okHttpCall);

前两个if判断主要是为了跳过object和object中内置的一些方法,除了这些,剩下的所有方法必然是我们在接口中定义的,也就是我们要拦截的。那么真正干事的就是三句:

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

其中loadServiceMethod()方法就是用来拼装http请求信息的,这个问题解决!

如何产生发起http请求对象的?

经过上面的分析, OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);这就很明显就是用来生产这个对象的。

如何将对象转换成我们在接口中指定的返回值的?

这里要说明下,之前我们定义接口的时候是这样的:

@GET("hello/world")  Call getNews(@Query("num") String num,@Query("page")String page);

这里的Call和Okhttp的Call其实很像,其实连方法都几乎一样,但是Retrofit和Rxjava一起用的时候又可以这样定义

@GET("book/search")  Observable getSearchBook(@Query("q") String name,                  @Query("tag") String tag, @Query("start") int start,                  @Query("count") int count);

这里指定的返回值不再是Call,而是变成了RxJava的Observable,所以这里肯定有一步转换,能将之前拼装的信息转换成我们指定的对象,具体核心就是最后一行的serviceMethod.adapt()干的。

感谢你能够认真阅读完这篇文章,希望小编分享的"Retrofit源码的示例分析"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

接口 方法 对象 就是 源码 代理 分析 信息 时候 动态 篇文章 明显 注解 流程 示例 实例 必然 网络 问题 面的 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 淮阴区佰能通软件开发工作室 非涉密网络安全保密制度 软件开发费用的税点 怎么用服务器提升效率 目前大国网络安全 趋势科技网络安全版卸载密码 湖南软件开发定制服务 威图服务器机柜尺寸 聊天机器人软件开发商 网络技术服务培训 dell服务器代理商查询 树莓派服务器端口有多大 专科学习计算机还是网络技术好 湖北人工智能软件开发靠谱吗 IC搜索软件开发 nexus 代理服务器 云服务器 网站无法访问 中央网络安全和信息化领导小组组长 杭州人工智能软件开发定制费用 网络安全专业的主要岗位 工商银行软件开发中心待遇 软件开发总监面试题 什么是软件开发合同 支付给个人的软件开发费用 互联网促进了科技创新的需要 软件开发如何加速 方舟手游服务器转单机教程 承德银行软件开发岗好不好 科技互联网创业公司 元数据库的目标及其技术要求
0