|
114 | 114 | <metaproperty="og:description"content="Glide源码解析(二):缓存机制本文是 Glide 源码分析系列的第二篇,主要通过分析源码总结 Glide 的缓存机制。 |
115 | 115 | 从加载流程揭开缓存机制的面纱首先回忆一下上一篇关于 Glide 加载流程源码分析的内容,我们从 Glide.with().load().into() 这个最简单最基本的用法入手,一步步深入源码,梳理出了完整的图片加载流程。由于当时分析重点在于整体流程的把握上,所以对于缓存相关"> |
116 | 116 | <metaproperty="og:image"content="http://o8swcawjo.bkt.clouddn.com/%E7%BC%93%E5%AD%98%E6%B5%81%E7%A8%8B.png"> |
117 | | -<metaproperty="og:updated_time"content="2017-05-08T03:42:42.000Z"> |
| 117 | +<metaproperty="og:updated_time"content="2017-05-08T03:44:44.000Z"> |
118 | 118 | <metaname="twitter:card"content="summary"> |
119 | 119 | <metaname="twitter:title"content="Glide源码解析(二):缓存机制"> |
120 | 120 | <metaname="twitter:description"content="Glide源码解析(二):缓存机制本文是 Glide 源码分析系列的第二篇,主要通过分析源码总结 Glide 的缓存机制。 |
@@ -435,6 +435,7 @@ <h2 id="Glide源码解析(二):缓存机制"><a href="#Glide源码解析 |
435 | 435 | <h3id="从加载流程揭开缓存机制的面纱"><ahref="#从加载流程揭开缓存机制的面纱"class="headerlink"title="从加载流程揭开缓存机制的面纱"></a>从加载流程揭开缓存机制的面纱</h3><p>首先回忆一下上一篇关于 Glide 加载流程源码分析的内容,我们从 Glide.with().load().into() 这个最简单最基本的用法入手,一步步深入源码,梳理出了完整的图片加载流程。由于当时分析重点在于整体流程的把握上,所以对于缓存相关的部分都是简单带过而没有进行深入分析。首先是为了避免文章篇幅过长,其次因为缓存它不是独立的部分,它埋藏在整个加载流程的各个环节中,所以对缓存机制的理解应该建立在对整体流程清晰的把握上。</p> |
436 | 436 | <p>而在本文中,我们将从整个加载流程入手,找出缓存相关的部分,进而还原出 Glide 缓存机制的整体面貌。然后再对各个部分进行详细分析。</p> |
437 | 437 | <p>那么我们开始来看看加载流程中被我们错过的缓存操作。</p> |
| 438 | +<aid="more"></a> |
438 | 439 | <h4id="发起请求前"><ahref="#发起请求前"class="headerlink"title="发起请求前"></a>发起请求前</h4><p>我们在 GenericRequestBuilder 中构建了一个 GenericRequest 实例并交给 RequestTracker 去处理,执行它的 begin() 方法。在 GenericRequest 的 确定了 ImageView 的大小之后在 onSizeReady() 回调中调用了 Engine 的load() 进行加载。这时我们第一次遇到了缓存操作</p> |
439 | 440 | <figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br><spanclass="line">26</span><br><spanclass="line">27</span><br><spanclass="line">28</span><br><spanclass="line">29</span><br><spanclass="line">30</span><br><spanclass="line">31</span><br><spanclass="line">32</span><br><spanclass="line">33</span><br><spanclass="line">34</span><br><spanclass="line">35</span><br><spanclass="line">36</span><br><spanclass="line">37</span><br><spanclass="line">38</span><br><spanclass="line">39</span><br><spanclass="line">40</span><br><spanclass="line">41</span><br><spanclass="line">42</span><br><spanclass="line">43</span><br><spanclass="line">44</span><br><spanclass="line">45</span><br><spanclass="line">46</span><br><spanclass="line">47</span><br><spanclass="line">48</span><br><spanclass="line">49</span><br><spanclass="line">50</span><br><spanclass="line">51</span><br><spanclass="line">52</span><br><spanclass="line">53</span><br><spanclass="line">54</span><br><spanclass="line">55</span><br><spanclass="line">56</span><br><spanclass="line">57</span><br><spanclass="line">58</span><br><spanclass="line">59</span><br><spanclass="line">60</span><br><spanclass="line">61</span><br><spanclass="line">62</span><br><spanclass="line">63</span><br><spanclass="line">64</span><br><spanclass="line">65</span><br><spanclass="line">66</span><br><spanclass="line">67</span><br><spanclass="line">68</span><br><spanclass="line">69</span><br><spanclass="line">70</span><br><spanclass="line">71</span><br><spanclass="line">72</span><br><spanclass="line">73</span><br><spanclass="line">74</span><br><spanclass="line">75</span><br><spanclass="line">76</span><br><spanclass="line">77</span><br><spanclass="line">78</span><br><spanclass="line">79</span><br><spanclass="line">80</span><br><spanclass="line">81</span><br><spanclass="line">82</span><br><spanclass="line">83</span><br><spanclass="line">84</span><br><spanclass="line">85</span><br><spanclass="line">86</span><br><spanclass="line">87</span><br><spanclass="line">88</span><br></pre></td><tdclass="code"><pre><spanclass="line">public class Engine implements EngineJobListener,</span><br><spanclass="line"> MemoryCache.ResourceRemovedListener,</span><br><spanclass="line"> EngineResource.ResourceListener {</span><br><spanclass="line"></span><br><spanclass="line"> public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,</span><br><spanclass="line"> DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,</span><br><spanclass="line"> Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {</span><br><spanclass="line"> ......</span><br><spanclass="line"></span><br><spanclass="line"> final String id = fetcher.getId();</span><br><spanclass="line"> EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),</span><br><spanclass="line"> loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),</span><br><spanclass="line"> transcoder, loadProvider.getSourceEncoder());</span><br><spanclass="line"></span><br><spanclass="line"> /// 从LruResourceCache中获取</span><br><spanclass="line"> EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);</span><br><spanclass="line"> if (cached != null) {</span><br><spanclass="line"> ///GenericRequest</span><br><spanclass="line"> cb.onResourceReady(cached);</span><br><spanclass="line"> if (Log.isLoggable(TAG, Log.VERBOSE)) {</span><br><spanclass="line"> logWithTimeAndKey("Loaded resource from cache", startTime, key);</span><br><spanclass="line"> }</span><br><spanclass="line"> return null;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> /// 从activeResources中获取</span><br><spanclass="line"> EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);</span><br><spanclass="line"> if (active != null) {</span><br><spanclass="line"> ///GenericRequest</span><br><spanclass="line"> cb.onResourceReady(active);</span><br><spanclass="line"> if (Log.isLoggable(TAG, Log.VERBOSE)) {</span><br><spanclass="line"> logWithTimeAndKey("Loaded resource from active resources", startTime, key);</span><br><spanclass="line"> }</span><br><spanclass="line"> return null;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> ......</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> private EngineResource<?> loadFromActiveResources(Key key, boolean isMemoryCacheable) {</span><br><spanclass="line"> if (!isMemoryCacheable) {</span><br><spanclass="line"> return null;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> EngineResource<?> active = null;</span><br><spanclass="line"> WeakReference<EngineResource<?>> activeRef = activeResources.get(key);</span><br><spanclass="line"> if (activeRef != null) {</span><br><spanclass="line"> active = activeRef.get();</span><br><spanclass="line"> if (active != null) {</span><br><spanclass="line"> active.acquire();</span><br><spanclass="line"> } else {</span><br><spanclass="line"> activeResources.remove(key);</span><br><spanclass="line"> }</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> return active;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> ///从LruResourceCache中获取,若有则移除并放入activesource</span><br><spanclass="line"> private EngineResource<?> loadFromCache(Key key, boolean isMemoryCacheable) {</span><br><spanclass="line"> if (!isMemoryCacheable) {</span><br><spanclass="line"> return null;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> EngineResource<?> cached = getEngineResourceFromCache(key);</span><br><spanclass="line"> if (cached != null) {</span><br><spanclass="line"> cached.acquire();</span><br><spanclass="line"> activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));</span><br><spanclass="line"> }</span><br><spanclass="line"> return cached;</span><br><spanclass="line"> }</span><br><spanclass="line"></span><br><spanclass="line"> @SuppressWarnings("unchecked")</span><br><spanclass="line"> private EngineResource<?> getEngineResourceFromCache(Key key) {</span><br><spanclass="line"> Resource<?> cached = cache.remove(key);</span><br><spanclass="line"></span><br><spanclass="line"> final EngineResource result;</span><br><spanclass="line"> if (cached == null) {</span><br><spanclass="line"> result = null;</span><br><spanclass="line"> } else if (cached instanceof EngineResource) {</span><br><spanclass="line"> // Save an object allocation if we've cached an EngineResource (the typical case).</span><br><spanclass="line"> result = (EngineResource) cached;</span><br><spanclass="line"> } else {</span><br><spanclass="line"> result = new EngineResource(cached, true /*isCacheable*/);</span><br><spanclass="line"> }</span><br><spanclass="line"> return result;</span><br><spanclass="line"> }</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure> |
440 | 441 | <p>程序首先调用 loadFromCache() 尝试从 MemoryCache 中获取,如果命中缓存则将缓存从 MemoryCache 中移除并放入 activeResources,然后返回。如果缓存失效则尝试从 activeResources 中获取,如果都失效再构建 EngineRunnable 从磁盘或者网络获取。</p> |
|