一、整体思路
从使用方法出发,首先是怎么使用,其次是我们使用的功能在内部是如何实现的,实现方案上有什么技巧,有什么范式。全文基本上是对改造源码的一个分析与导读,非常建议大家下载改造源码之后,跟着本文,过一遍源码。
<强>上图知识汇总的PDF 强>相关内容后续GitHub更新,想冲击金三银四的小伙伴可以找找看看,欢迎星
引用>
(<强>顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找强>)
https://github.com/xiangjiana/Android-MS
<强> (VX: mm14525201314) 强>二,基本用例
2.1创建改造对象
<代码>翻新改造=new Retrofit.Builder () .baseUrl (“https://api.github.com/? .addConverterFactory (GsonConverterFactory.create ()) .build(); 代码>2.2定义API并获取API实例
<代码>公共接口GitHubService { @ get(“用户/{user}/回购”) Call比;listRepos @ path(“用户”)字符串(用户); } GitHubService github=retrofit.create (GitHubService.class); 代码>
先看定义,非常简洁,也没有什么特别之处,除了两个注解:<代码> @ get 代码>和<代码> @ path> 代码。它们的用处稍后再分析,我们接着看创建API实例:<代码> retrofit.create (GitHubService.class)> 代码。这样就创建了API实例了,就可以调用API的方法发起HTTP网络请求了,太方便了。但<代码>创建代码> 方法是怎么创建API实例的呢?
<代码>公共& lt; T>T创建(最终Class服务){//省略非关键代码 返回(T) Proxy.newProxyInstance (service.getClassLoader (), 新Class<?在[]}{服务, 新的InvocationHandler () { @Override 公共对象调用对象代理、方法方法,对象……args) {抛出Throwable//先省略实现 } }); }代码> 创建API实例使用的是动态代理技术。
简而言之,就是动态生成接口的实现类(当然生成实现类有缓存机制),并创建其实例(称之为代理),代理把对接口的调用转发给<代码> InvocationHandler 代码>实例,而在<代码> InvocationHandler> 代码的实现中,除了执行真正的逻辑(例如再次转发给真正的实现类对象),我们还可以进行一些有用的操作,例如统计执行时间,进行初始化和清理,对接口调用进行检查等。为什么要用动态代理?因为对接口的所有方法的调用都会集中转发到<代码> InvocationHandler #调用代码> 函数中,我们可以集中进行处理,更方便的了。你可能会想,我也可以手写这样的代理类,把所有接口的调用都转发到<代码> InvocationHandler #调用代码>呀,当然可以,但是可靠地自动生成岂不更方便?
2.3调用API方法
获取到API实例之后,调用方法和普通的代码没有任何区别:
<代码> Call比;调用=github.listRepos(“广场”); List
回购=call.execute () .body(); 代码> 这两行代码就发出了HTTP请求,并把返回的数据转化为了<代码> List&肝移植;Repo& gt;> 代码,太方便了!
现在我们来看看调用<代码> listRepos> 代码是怎么发出HTTP请求的。上面改造#创建方法返回时省略的代码如下:
<代码>返回(T) Proxy.newProxyInstance (service.getClassLoader (), 新Class<?在[]}{服务, 新的InvocationHandler () { 私人最终平台平台=Platform.get (); @Override 公共对象调用对象代理、方法方法,对象. .。args) {抛出Throwable//如果方法是一种方法从对象然后推迟到n正常调用。 如果(method.getDeclaringClass ()==Object.class) { 方法返回。调用(这一点,args); } 如果(platform.isDefaultMethod(方法)){ 返回平台。invokeDefaultMethod(方法、服务p罗克西,args); } ServiceMethod ServiceMethod=loadServiceMethod(方法); OkHttpCall OkHttpCall=new OkHttpCall<祝辞(serviceMethod, args); 返回serviceMethod.callAdapter.adapt (okHttpCall); } });代码>如果调用的是<代码> 代码>对象的方法,例如<代码>=代码>,<代码> toString> 代码,那就直接调用。如果是<代码> 代码>违约方法(Java 8引入),就调用<代码> 代码>违约方法。这些我们都先不管,因为我们在安卓平台调用<代码> listRepos> 代码,肯定不是这两种情况,那这次调用真正干活的就是这三行代码了(好好记住这三行代码,因为接下来很长的篇幅都是在讲它们:)):
阿里二面:关于改造你知道多少吗?