Glide 三部曲之 Gif 加載原理

本篇文章已授權(quán)微信公眾號 guolin_blog (郭霖)獨家發(fā)布

  • 本文章所使用的 Glide 源碼版本:4.11.0

上一篇:Glide 三部曲之圖片加載流程

開胃菜

  • 在講之前,我們先補充一點基礎(chǔ)知識,安卓 ImageView 支不支持加載 Gif 動圖呢?其實是不支持的,因為 ImageView 本身就是一個 View,View 的繪制需要用 Canvas,而 Canvas 只支持 canvas.drawBitmap,也就是同一時間只能繪制一張位圖,而 Gif 是由多幀圖片組成,那么 Glide 是如何讓 ImageView 實現(xiàn)播放 Gif 動圖呢?
  • 還是從 Glide 給我們提供的寫法來入手這塊的源碼
  • 一上來就發(fā)現(xiàn)了今天的主角:GifDrawable
  • 確認過眼神,是想要的類
  • 那么問題來了,這個類有將近 500 多行代碼,我們該從哪里看起?
  • 這就跟看書類似,我們可以先看目錄,在源碼中也差不多,只不過它叫代碼結(jié)構(gòu)

源碼解析

  • 通過查看代碼結(jié)構(gòu),我們發(fā)現(xiàn)了一個方法,從方法名上理解,它是開始播放第一幀的方法,那么我們就從這個方法入手
  • 我們可以看到當 Gif 只有一幀的時候,會直接調(diào)用繪制方法,而 Gif 不止一幀的時候,那么它就開啟了訂閱,接下來讓我們看看這個訂閱的方法里面做了什么事情
  • 接下來讓我們重點看一下這三句代碼分別做了什么事
  • 看到這里我們大概明白了,這個方法是用來遞增幀位置的,從它的算法來看,這還是一個無限輪播的算法
  • 看完了 advance 的作用,我們回去接著看剩下的兩句代碼
  • 是不是忽然有點蒙,這個類是什么,我們先看一下它的父類
  • 是不是有點似曾相識,但就是怎么也說不出來什么,讓我們先看看它的父類
  • 這個 Target 就是我們上篇講到圖片加載流程提到過的接口

  • 這個接口的作用就是回調(diào)一些加載監(jiān)聽,這個接口前面三個方法分別是:加載開始、加載失敗、加載成功讀取資源的回調(diào)

  • 現(xiàn)在我們知道了這個是加載資源的回調(diào),那么它又是從哪里調(diào)用的?
  • 就是在我們后面要講的第三句代碼里面調(diào)用的,真是讓人意想不到
  • 我們看到在加載資源的回調(diào)中發(fā)送了一個消息,那么這個消息最終是去了哪里,接下來讓我們根據(jù)這個消息的 what 參數(shù)進行跟蹤
  • 看到 handleMessage 忽然有了一種熟悉的味道,我們看到這里主要處理了兩種消息,一種是延遲消息,一種是清理消息。接下來讓我們先看看,如果這是一個延遲消息會發(fā)生什么事
  • 在這里我們看到,它會先獲取當前幀數(shù)據(jù),然后再通過 Canvas.drawBitmap 到 ImageView 上面,接下來我們回去剛剛那個方法里面,看看它還做了些什么
  • 原來如此,它在刷新新的一幀數(shù)據(jù)到 ImageView 之后,會對舊的一幀數(shù)據(jù)進行清除

  • 然后再回去繼續(xù)看,它還做了什么事

  • 還是原來的方法,還是熟悉的三句代碼

總結(jié)

  • Glide 加載 Gif 的原理比較簡單,就是將 Gif 解碼成多張圖片進行無限輪播,每幀切換都是一次圖片加載請求,再加載到新的一幀數(shù)據(jù)之后會對舊的一幀數(shù)據(jù)進行清除,然后再繼續(xù)下一幀數(shù)據(jù)的加載請求,以此類推,使用 Handler 發(fā)送消息實現(xiàn)循環(huán)播放。

下一篇:Glide 番外篇之判斷圖片的類型

Android 技術(shù)討論 Q 群:10047167

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容