Android圖片載入庫的選擇與如何封裝?

由於項目需要重構,之前用的UIL庫作者已經不再維護,所以考慮切換圖片載入庫,項目組有需求將圖片載入等第三方庫進行封裝,這樣可以保證在切換庫時保證對外的代碼無改動,想請教下需要怎麼做,或者用哪種設計模式更好?另外圖片載入庫的選擇也有問題,了解到現在比較火的項目有(以下介紹摘抄自網路資料):

1、Picasso,Square公司的開源項目,據說和Square的網路庫一起能發揮最大作用。

2、Fresco,FB的明星項目,也是去年最火的項目之一,匿名共享緩存等機制保證低端機表現極佳,但是源代碼基於C/C++,閱讀困難度提升。

3、Glide,Google員工私人項目,但是Google很多項目在用,相對Picasso在Gif方面有優勢。

這是我做的一點功課,希望各位給給出意見和理由,謝謝。


謝邀。

有關圖片載入好像現在也就這麼幾個了。

(來自吳更新MDCC上的演講圖:Picasso的架構)

Picasso :之所以說和Square的網路庫一起能發揮最大作用,是因為Picasso可以選擇將網路請求的緩存部分交給了 okhttp 去實現 詳情見[OkHttp3Downloader](picasso/OkHttp3Downloader.java at master · square/picasso · GitHub)

(來自吳更新MDCC上的演講圖:Glide的架構)

Glide:模仿了Picasso的API,而且在他的基礎上加了很多的擴展(比如gif等支持)

他們兩者最大的區別在於默認的設置不同,Glide默認的Bitmap格式是RGB_565 ,比Picasso默認的ARGB_8888格式的內存開銷要小一半;Picasso緩存的是全尺寸的(只緩存一種),而Glide緩存的是跟ImageView尺寸相同的(即56*56和128*128是兩個緩存)

這兩者的詳細比較可參考:Introduction to Glide, Image Loader Library for Android, recommended by Google :: The Cheese Factory, Android 三大圖片緩存原理、設計、分層、特性上對比

FB的圖片載入框架Fresco:最大的優勢在於5.0以下(最低2.3)的bitmap載入。在5.0以下系統,Fresco將圖片放到一個特別的內存區域(Ashmem區)。當然,在圖片不顯示的時候,佔用的內存會自動被釋放。這會使得APP更加流暢,減少因圖片內存佔用而引發的OOM。為什麼說是5.0以下,因為在5.0以後系統默認就是存儲在Ashmem區了。

詳細可參看:android-tech-frontier/others/FaceBook推出的Android圖片載入庫-Fresco at master · bboyfeiyu/android-tech-frontier · GitHub , Fresco | Fresco 中文說明

其實還有一種圖片載入:自己寫。別笑,如果你們的APP對apk的大小有著極致的追求,可以嘗試基於Volley中提供的網路圖片請求來擴展出一個對你們自己APP最合適的圖片請求庫。這絕對是最小的體積。至於你問的封裝方法,可以看看 kymjs/RxVolley: RxVolley = Volley + RxJava ...

最後,簡單粗暴的一句話概括:

Picasso所能實現的功能,Glide都能做,無非是所需的設置不同。但是Picasso體積比起Glide小太多如果項目中網路請求本身用的就是okhttp或者retrofit(本質還是okhttp),那麼建議用Picasso,體積會小很多(Square全家桶的幹活)。Glide的好處是大型的圖片流,比如gif、Video,如果你們是做美拍、愛拍這種視頻類應用,建議使用。

Fresco在5.0以下的內存優化非常好,代價就是體積也非常的大,按體積算Fresco&>Glide&>Picasso

不過在使用起來也有些不便(小建議:他只能用內置的一個ImageView來實現這些功能,用起來比較麻煩,我們通常是根據Fresco自己改改,直接使用他的Bitmap層)


請看Trinea的這篇文章:

Android 三大圖片緩存原理、特性對比 @codeKK Android 開源站


樓上答的應該都偏題了,題主首先問的是如何對第三方圖片載入庫進行封裝,「保證在切換庫時保證對外的代碼無改動「。

其實就提供一個統一的入口,一個類的事情:

public class ImageLoader {
public static void with(Context context, String imageUrl, ImageView imageView) {
Picasso.with(context).load(imageUrl).into(imageView);
}
}

這樣以後要換成Glide的話直接改成:

public class ImageLoader {
public static void with(Context context, String imageUrl, ImageView imageView) {
Glide.with(context).load(imageUrl).into(imageView);
}
}

當然,這是最基礎的封裝,實際使用過程中肯定會有具體的需求,比如圖片佔位符的設置、圓角圖片、WiFi下不顯示圖片等等,可以進一步封裝。

具體的實踐可以看看這篇文章:

網路圖片載入的封裝【從零開始搭建android框架系列(4)】

其次圖片載入庫用過三種,ImageLoader、Fresco、Glide。

ImageLoader配置比較多,靈活性高;

Fresco速度快,但包體積大(因此後來換成了Glide),還會出現圖片莫名其妙載入不出來的情況,而且底層源碼是C++,不太好Debug;

Glide,輕量,使用方便,但容易出Bug,比如不能在子線程載入圖片;

總結一句話就是:公司用啥你就用啥。如果是自己的項目就無所謂了,喜歡哪個用哪個。


自己封裝的一個小圖片載入庫(包括相機相冊的圖片提供)GitHub - Zane96/EasyImage: 運用在安卓開發上提供本地,緩存,網路三方圖片的快速開發庫


項目實戰,分享了Github源碼,Android圖片載入庫的封裝實戰之路 - s003603u的專欄 - 博客頻道 - CSDN.NET


我的意見是慎用Glide,Glide封裝我特別的喜歡,但是性能真的很差...


推薦閱讀:

在Android開發過程中搭建一個自己的應用框架有幾個步驟?需要注意什麼?
為什麼除 Nexus 以外的 Android 舊設備都很少且很慢得到系統升級?
自學Android開發?
為什麼PC配置那麼好,跑安卓虛擬機還是卡,是技術原因,還是硬體原因?
?

單片機、ARM、嵌入式開發、Android 底層開發有什麼關係?

TAG:Android開發 | Android | Android工程師 |