衆所周知,優秀源碼的閱讀與理解是最能提高自身功力的途徑,若是想要成爲一名優秀的Android工程師,那麼Android中優秀三方庫源碼的分析和理解則是必備技能。就拿比較熱門的圖片加載框架Glide來講,相信不少同窗都使用過,那麼,當別人問你下面這些問題時你是否能回答出來呢?(Glide五連發)android
相信能所有回答出來的同窗並很少,下面我來解答一下上面幾個問題。git
要想了解Glide的核心實現原理,就必須先從它的加載API Glide.with().into()來進行分析。github
設置請求url,並記錄url已設置的狀態。面試
其中Glide的三層緩存機制是值得咱們去反覆學習揣摩的,這裏咱們先了解下常規的三級緩存是怎樣的。數據庫
當咱們的APP中想要加載某張圖片時,先去LruCache中尋找圖片,若是LruCache中有,則直接取出來使用,若是LruCache中沒有,則去SoftReference中尋找(軟引用適合當cache,當內存吃緊的時候纔會被回收。而weakReference在每次system.gc()就會被回收)(當LruCache存儲緊張時,會把最近最少使用的數據放到SoftReference中),若是SoftReference中有,則從SoftReference中取出圖片使用,同時將圖片從新放回到LruCache中,若是SoftReference中也沒有圖片,則去硬盤緩存中中尋找,若是有則取出來使用,同時將圖片添加到LruCache中,若是沒有,則鏈接網絡從網上下載圖片。圖片下載完成後,將圖片保存到硬盤緩存中,而後放到LruCache中。編程
Glide緩存機制大體分爲三層:內存緩存、弱引用緩存、磁盤緩存。json
三層存儲的機制在Engine中實現的。先說下Engine是什麼?Engine這一層負責加載時作管理內存緩存的邏輯。持有MemoryCache、Map<Key, WeakReference<EngineResource<?>>>。經過load()來加載圖片,加載先後會作內存存儲的邏輯。若是內存緩存中沒有,那麼纔會使用EngineJob這一層來進行異步獲取硬盤資源或網絡資源。EngineJob相似一個異步線程或observable。Engine是一個全局惟一的,經過Glide.getEngine()來獲取。設計模式
須要一個圖片資源,若是Lrucache中有相應的資源圖片,那麼就返回,同時從Lrucache中清除,放到activeResources中。activeResources map是盛放正在使用的資源,以弱引用的形式存在。同時資源內部有被引用的記錄。若是資源沒有引用記錄了,那麼再放回Lrucache中,同時從activeResources中清除。若是Lrucache中沒有,就從activeResources中找,找到後相應資源引用加1。若是Lrucache和activeResources中沒有,那麼進行資源異步請求(網絡/diskLrucache),請求成功後,資源放到diskLrucache和activeResources中。緩存
使用一個弱引用map activeResources來盛放項目中正在使用的資源。Lrucache中不含有正在使用的資源。資源內部有個計數器來顯示本身是否是還有被引用的狀況,把正在使用的資源和沒有被使用的資源分開有什麼好處呢??由於當Lrucache須要移除一個緩存時,會調用resource.recycle()方法。注意到該方法上面註釋寫着只有沒有任何consumer引用該資源的時候才能夠調用這個方法。那麼爲何調用resource.recycle()方法須要保證該資源沒有任何consumer引用呢?glide中resource定義的recycle()要作的事情是把這個不用的資源(假設是bitmap或drawable)放到bitmapPool中。bitmapPool是一個bitmap回收再利用的庫,在作transform的時候會從這個bitmapPool中拿一個bitmap進行再利用。這樣就避免了從新建立bitmap,減小了內存的開支。而既然bitmapPool中的bitmap會被重複利用,那麼確定要保證回收該資源的時候(即調用資源的recycle()時),要保證該資源真的沒有外界引用了。這也是爲何glide花費那麼多邏輯來保證Lrucache中的資源沒有外界引用的緣由。網絡
圖片佔用內存的計算公式:圖片高度 * 圖片寬度 * 一個像素佔用的內存大小。因此,計算圖片佔用內存大小的時候,要考慮圖片所在的目錄跟設備密度,這兩個因素其實影響的是圖片的寬高,android會對圖片進行拉昇跟壓縮。
上面筆者只是簡單地講解一下下Glide的內部實現機制,可是這是遠遠不夠的,若是想要對Glide或其它熱門三方庫有足夠具象地瞭解,就必須深刻源碼去感覺其中的藝術。
所以,爲了將熱門三方庫涉及的知識成體系地融合起來,筆者建立了Awesome-Third-Library-Source-Analysis這個項目,爲的就是讓每個Android工程師可以從如下七個方面全方位地提高本身的技術實力。
項目地址:Awesome-Third-Library-Source-Analysis
深刻理解熱門三方庫實現原理,從七個角度全方位提高你的功力~
Android最優秀的網絡底層框架,沒有之一。
Android最優秀的網絡封裝框架,內含九種經常使用設計模式的靈活運用。
Android使用最普遍的圖片加載框架。
Android中數據庫操做綜合效率最高的框架。
來一塊兒探究RxJava的異步、簡潔、優雅和它強大的操做符吧!
LeakCanary到底是如何檢測出內存泄露的呢?
使用APT + 註解攻破了findViewByid(),JW大神之做。
Dagger就一把匕首,在中大型項目中,它能提高開發效率、自動管理類的實例、解耦,是如此的乾脆。
使用擴展的觀察者模式實現的組件間通訊框架,廣播的替代者。
做者:jsonchao
連接:https://juejin.im/post/5e65ad276fb9a07cc01a3264來源:掘金