<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>源码阅读 on lfkdsk's Blog</title><link>https://blog.lfkdsk.org/tags/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/</link><description>Recent content in 源码阅读 on lfkdsk's Blog</description><generator>Hugo</generator><language>cn</language><lastBuildDate>Thu, 24 Aug 2017 19:50:32 +0000</lastBuildDate><atom:link href="https://blog.lfkdsk.org/tags/%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/index.xml" rel="self" type="application/rss+xml"/><item><title>Retrofit 实现分析</title><link>https://blog.lfkdsk.org/read-retrofit/</link><pubDate>Thu, 24 Aug 2017 19:50:32 +0000</pubDate><guid>https://blog.lfkdsk.org/read-retrofit/</guid><description>&lt;p>Retrofit 为我们提供了一种非常优雅的方式去书写 Restful 的请求的接口代码，和 OkHttp 、Rxjava 都能方便的无缝搭配，为我们在 Java 和 Android 提供了非常便捷的网络请求的编写方式。这篇文章中我们会从 Usage 出发，逐个步骤的分析 Retrofit 的实现方式。&lt;/p>
&lt;h2 id="实现分析">实现分析&lt;/h2>
&lt;p>我们可以定义这样的一个接口，代表一种 restful 请求：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">interface&lt;/span> &lt;span style="color:#a6e22e">GitHubService&lt;/span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@GET&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;users/{user}/repos&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Call&lt;span style="color:#f92672">&amp;lt;&lt;/span>List&lt;span style="color:#f92672">&amp;lt;&lt;/span>Repo&lt;span style="color:#f92672">&amp;gt;&amp;gt;&lt;/span> &lt;span style="color:#a6e22e">listRepos&lt;/span>(&lt;span style="color:#a6e22e">@Path&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;user&amp;#34;&lt;/span>) String user);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>在使用 Retrofit 的时候：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>Retrofit retrofit &lt;span style="color:#f92672">=&lt;/span> &lt;span style="color:#66d9ef">new&lt;/span> Retrofit.&lt;span style="color:#a6e22e">Builder&lt;/span>()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">baseUrl&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;https://api.github.com/&amp;#34;&lt;/span>)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> .&lt;span style="color:#a6e22e">build&lt;/span>();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>GitHubService service &lt;span style="color:#f92672">=&lt;/span> retrofit.&lt;span style="color:#a6e22e">create&lt;/span>(GitHubService.&lt;span style="color:#a6e22e">class&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>我们通过 &lt;strong>Builder&lt;/strong> 模式拼好 baseUrl 等字串，通过 retrofit 对象可以创建我们的接口对应的实体类，我们通过对这个实体类的操作，就能对我们定义好的接口去请求对应的数据：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>Call&lt;span style="color:#f92672">&amp;lt;&lt;/span>List&lt;span style="color:#f92672">&amp;lt;&lt;/span>Repo&lt;span style="color:#f92672">&amp;gt;&amp;gt;&lt;/span> repos &lt;span style="color:#f92672">=&lt;/span> service.&lt;span style="color:#a6e22e">listRepos&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;octocat&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="创建请求类">创建请求类&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span> &lt;span style="color:#a6e22e">@SuppressWarnings&lt;/span>(&lt;span style="color:#e6db74">&amp;#34;unchecked&amp;#34;&lt;/span>) &lt;span style="color:#75715e">// Single-interface proxy creation guarded by parameter safety.&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#f92672">&amp;lt;&lt;/span>T&lt;span style="color:#f92672">&amp;gt;&lt;/span> T &lt;span style="color:#a6e22e">create&lt;/span>(&lt;span style="color:#66d9ef">final&lt;/span> Class&lt;span style="color:#f92672">&amp;lt;&lt;/span>T&lt;span style="color:#f92672">&amp;gt;&lt;/span> service) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Utils.&lt;span style="color:#a6e22e">validateServiceInterface&lt;/span>(service);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (validateEagerly) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> eagerlyValidateMethods(service);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> (T) Proxy.&lt;span style="color:#a6e22e">newProxyInstance&lt;/span>(service.&lt;span style="color:#a6e22e">getClassLoader&lt;/span>(), &lt;span style="color:#66d9ef">new&lt;/span> Class&lt;span style="color:#f92672">&amp;lt;?&amp;gt;[]&lt;/span>{service}, &lt;span style="color:#66d9ef">new&lt;/span> InvocationHandler() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// ... 省略&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这里我们先是对 class 对象的类型做了检测保证了是 Interface 而且没有多继承，并且在开了 &lt;code>validateEagerly&lt;/code> 的情况下会对 Service 里面的请求接口进行 Cache：&lt;/p></description></item></channel></rss>