原來Glide是這樣加載GIF圖的

一名優秀的Android開發,需要一份完備的 知識體系,在這裏,讓我們一起成長爲自己所想的那樣~。

/   開胃菜   /

在講之前,我們先補充一點基礎知識,安卓 ImageView 支不支持加載 Gif 動圖呢?其實是不支持的,因爲 ImageView 本身就是一個 View,View 的繪製需要用 Canvas,而 Canvas 只支持 canvas.drawBitmap,也就是同一時間只能繪製一張位圖,而 Gif 是由多幀圖片組成,那麼 Glide 是如何讓 ImageView 實現播放 Gif 動圖呢?

還是從 Glide 給我們提供的寫法來入手這塊的源碼

一上來就發現了今天的主角:GifDrawable

確認過眼神,是想要的類

那麼問題來了,這個類有將近 500 多行代碼,我們該從哪裏看起?

這就跟看書類似,我們可以先看目錄,在源碼中也差不多,只不過它叫代碼結構

/   源碼解析   /

通過查看代碼結構,我們發現了一個方法,從方法名上理解,它是開始播放第一幀的方法,那麼我們就從這個方法入手

我們可以看到當 Gif 只有一幀的時候,會直接調用繪製方法,而 Gif 不止一幀的時候,那麼它就開啓了訂閱,接下來讓我們看看這個訂閱的方法裏面做了什麼事情

接下來讓我們重點看一下這三句代碼分別做了什麼事

看到這裏我們大概明白了,這個方法是用來遞增幀位置的,從它的算法來看,這還是一個無限輪播的算法

看完了 advance 的作用,我們回去接着看剩下的兩句代碼

是不是忽然有點蒙,這個類是什麼,我們先看一下它的父類

是不是有點似曾相識,但就是怎麼也說不出來什麼,讓我們先看看它的父類

這個 Target 就是我們上篇講到圖片加載流程提到過的接口

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

現在我們知道了這個是加載資源的回調,那麼它又是從哪裏調用的?

就是在我們後面要講的第三句代碼裏面調用的,真是讓人意想不到

我們看到在加載資源的回調中發送了一個消息,那麼這個消息最終是去了哪裏,接下來讓我們根據這個消息的 what 參數進行跟蹤

看到 handleMessage 忽然有了一種熟悉的味道,我們看到這裏主要處理了兩種消息,一種是延遲消息,一種是清理消息。接下來讓我們先看看,如果這是一個延遲消息會發生什麼事

在這裏我們看到,它會先獲取當前幀數據,然後再通過 Canvas.drawBitmap 到 ImageView 上面,接下來我們回去剛剛那個方法裏面,看看它還做了些什麼

原來如此,它在刷新新的一幀數據到 ImageView 之後,會對舊的一幀數據進行清除

然後再回去繼續看,它還做了什麼事

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

/   總結   /

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

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