Glide框架解析---調用流程(三)

前兩篇主要介紹了Glide的緩存機制和註冊器,但是這兩篇並不是Glide的核心功能,只能算是深入瞭解Glide的鋪墊工作。調用流程的理解,會讓你深入的瞭解Glide的工作過程和源碼,這篇開始,我們正式進入Glide的核心部分。

Glide的調用流程,相對比較複雜,涉及的類和方法都比較多,如果直接進入源碼一步一步的待着大家看,可能看到後面,前面的就忘記了,所以我這裏畫了一張調用Glide加載圖片時其內部的流程,如下圖,直接看圖可能會懵,所以一定要結合下面的解釋一起理解:

Glide.with(this).load(filePath).into(iamgeView);

Glide的調用最簡單的就是上面的用法,上圖呢就是以此流程用法爲例進行解析。

第一部分:

從調用類執行Glide.with開始,一直到into方法調用之前,其實都是比較簡單的。雖然我們暫時還不清楚RequestManagerRetriever,RequestManagerFragment,RequestManager這三個類是幹嘛的,但是並不影響我們之後流程的理解,你會發現,into之後的流程基本和這三個類沒有關係。

第二部分:

into方法是RequestBuilder類中的方法,這個方法的內部會創建一個Request對象,進入Request這個類你會發現,它其實是一個接口類,那接口類是誰呢?

Request request = buildRequest(target, targetListener, options);

我們從into方法中的這句代碼層層的往上找,最後定位在obtainRequest方法中

return SingleRequest.obtain(...);

所以我們確定這個Request的實現類,其實是SingleRequest

在into方法的最後,調用了RequestManager對象的trace方法,出入了ImageView對象和SingleRequest對象

  void track(@NonNull Target<?> target, @NonNull Request request) {
    targetTracker.track(target);
    requestTracker.runRequest(request);
  }

targetTracker我們暫時忽略,我們主要看requestTracker.runReqeust方法。內部代碼很簡單,調用了SingleRequest對象的begin方法(如上圖中的begin方法),begin方法內部調用了自己的onSizeReady方法,然後調用了Engine對象的load方法

第三部分:

到了這裏,就到了我們前兩篇提到的內存緩存了,內存緩存包括了活動緩存內存緩存。我們直接看代碼:

    //從活動緩存中查找
    EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
    if (active != null) {
      cb.onResourceReady(active, DataSource.MEMORY_CACHE);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from active resources", startTime, key);
      }
      return null;
    }
    //從內存緩存中查找
    EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
    if (cached != null) {
      cb.onResourceReady(cached, DataSource.MEMORY_CACHE);
      if (VERBOSE_IS_LOGGABLE) {
        logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return null;
    }

如代碼中所示,loadFromActiveResources是從活動資源中查找所需圖片,如果沒有則從內存緩存中查找圖片;找到圖片後通過調用onResourceReady方法,回調給Request,也就是SingleRequest。具體的代碼同學們可以自行翻閱去看,你會找到很多之前說過的代碼。

如果活動緩存和內存緩存中都沒有所需的圖片資源,則會創建一個EngineJob和DecodeJob對象。EngineJob沒有什麼特別的功能,主要負責回調和管理工作,而DecodeJob呢,這個類的註釋說的很清楚,負責從緩存數據或原始數據中解碼資源,並應用轉換和轉碼的類。DecodeJob實現了Runnable接口,那一定有某個類開啓了這個線程,這個類就是EngineJob。

上面說到,EngineJob和DecodeJob對象被創建,之後

engineJob.start(decodeJob);

start方法如下:

  public void start(DecodeJob<R> decodeJob) {
    this.decodeJob = decodeJob;
    GlideExecutor executor = decodeJob.willDecodeFromCache()
        ? diskCacheExecutor
        : getActiveSourceExecutor();
    executor.execute(decodeJob);
  }

其實就是一個線程池,然後執行了decodeJob這個線程,之後開始執行decodeJob中run方法的內容,進入第四部分

第四部分:

這部分呢,主要分爲三塊:

(1)從資源緩存(ResourceCacheGenerator)中查找圖片,這個緩存是第一篇文章說過的第三個緩存,主要存儲解碼後的圖片資源,找到後層層回調給Request(SingleRequest)

(2)如果資源緩存中沒有,則從原始緩存(DataCacheGenerator)中查找圖片,這個緩存是第四個緩存,存儲的圖片是原始數據,基本上都會存在手機的SDCard中

(3)如果上面兩個都沒有,就是從圖片地址(SourceCacheGenerator)中查找(網絡就從網絡中找,本地的就從本地中找)

 

以上就是今天的全部內容,看似篇幅不多,但是需要反覆的去源碼中翻看,只有把源碼翻熟翻透,才能明白流程。今天沒有代碼,下片說完生命週期再統一分享。

歡迎大家提問與糾錯!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章