Android圖片加載

老生常談了兑宇,但是還是有很多細節(jié)不知道的碍侦。先挖個坑,后面慢慢埋~

圖片加載框架隶糕?

  1. Picasso
  2. Glide
  3. Fresco

Picasso:

Picasso :和Square的網絡庫一起能發(fā)揮最大作用瓷产,因為Picasso可以選擇將網絡請求的緩存部分交給了okhttp實現。

Glide:模仿了Picasso的API枚驻,而且在他的基礎上加了很多的擴展(比如gif等支持)拦英,Glide默認的Bitmap格式是RGB_565,比    Picasso默認的ARGB_8888格式的內存開銷要小一半测秸;Picasso緩存的是全尺寸的(只緩存一種)疤估,而Glide緩存的是跟ImageView尺寸相同的(即56*56和128*128是兩個緩存) 。

FB的圖片加載框架Fresco:最大的優(yōu)勢在于5.0以下(最低2.3)的bitmap加載霎冯。在5.0以下系統(tǒng)铃拇,Fresco將圖片放到一個特別的內存區(qū)域(Ashmem區(qū))。當然沈撞,在圖片不顯示的時候慷荔,占用的內存會自動被釋放。這會使得APP更加流暢缠俺,減少因圖片內存占用而引發(fā)的OOM显晶。為什么說是5.0以下贷岸,因為在5.0以后系統(tǒng)默認就是存儲在Ashmem區(qū)了。

Fresco性能上的優(yōu)點
優(yōu)一:
1磷雇、支持webp格式的圖片偿警,是Google官方推行的,它的大小比其它格式圖片的大小要小一半左右唯笙,目前各個大公司都漸入的使用這種圖片格式了螟蒸,比如:Youtube、Gmail崩掘、淘寶七嫌、QQ空間等都已嘗鮮,使用該格式最大的優(yōu)點就是輕量苞慢、省流量诵原、圖片加載迅速。而Fresco是通過jni來實現支持WebP格式圖片挽放。

優(yōu)二:
2、5.0以下系統(tǒng):使用”ashmem”(匿名共享內存)區(qū)域存儲Bitmap緩存骂维,這樣Bitmap對象的創(chuàng)建、釋放將永遠不會觸發(fā)GC贺纲,關于”ashmem”存儲區(qū)域航闺,它是一個不在Java堆區(qū)的一片存儲內存空間,它的管理由Linux內核驅動管理猴誊,不必深究潦刃,只要知道這塊存儲區(qū)域是別于堆內存之外的一塊空間就行了,且這塊空間是可以多進程共享的懈叹,GC的活動不會影響到它乖杠。5.0以上系統(tǒng),由于內存管理的優(yōu)化澄成,所以對于5.0以上的系統(tǒng)Fresco將Bitmap緩存直接放到了堆內存中胧洒。

關于”ashmem”的存儲區(qū)域,我們的應用程序并不能像訪問堆內存一樣直接訪問這塊內存塊墨状,但是也有一些例外卫漫,對于Bitmap而言,有一種為”Purgeable Bitmap”可擦除的Bitmap位圖是存儲在這塊內存區(qū)域中的肾砂,BitmapFactory.Options中有這么一個屬性 inPurgeable :

BitmapFactory.Options = new BitmapFactory.Options();
options.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length, options);
所以通過配置inPurgeable = true這個屬性列赎,這樣解碼出來的Bitmap位圖就存儲在”ashmem”區(qū)域中,之后用到”ashmem”中得圖片時镐确,則把這個圖片從這個區(qū)域中取出來包吝,渲染完畢后則放回這個位置饼煞。

既然Fresco中Bitmap緩存在5.0以前是放在”ashmem”中,GC并不會回收它們诗越,且也不會被”ashmeme”內置的清除機制回收它們砖瞧,所以這樣雖然使得在堆中不會造成內存泄露,而在這塊區(qū)域可能造成內存泄露掺喻,Fresco中采取的辦法則是使用引用計數的方式芭届,其中有一個SharedReference這個類,這個類中有這么兩個方法:addReference()和deleteReference()感耙,通過這兩個基本方法來對引用進行計數褂乍,一旦計數為零時,則對應的資源將會清除(如:Bitmap.recycle()等)即硼,而Fresco為了考慮更容易被我們使用逃片,又提供了一個CloseableReference類,該類可以說是SharedReference類上功能的封裝只酥,CloseableReference同時也實現了Cloneable褥实、Closeable接口,它在調用.clone()方法時同時會調用addReference()來增加一個引用計數裂允,在調用.close()方法時同時會調用deleteReference()來刪除一個引用計數损离,所以在使用Fresco的使用,我們都是與CloseableReference類打交道绝编,使用CloseableReference必須遵循以下兩條規(guī)則:

1僻澎、在賦值CloseableReference給新對象的時候,調用.clone()進行賦值

2十饥、在超出作用域范圍的時候窟勃,必須調用.close(),通常會在finally代碼塊中調用

void gee() {
CloseableReference<Val> ref = foo();
try {
haa(ref);
} finally {
ref.close();
}
}
遵循這些規(guī)則可以有效地防止內存泄漏逗堵。

優(yōu)三:
3秉氧、使用了三級緩存:Bitmap緩存+未解碼圖片緩存+硬盤緩存。其中前兩個就是內存緩存蜒秤,Bitmap緩存根據系統(tǒng)版本不同放在了不同內存區(qū)域中汁咏,而未解碼圖片的緩存只在堆內存中,Fresco分了兩步做內存緩存作媚,這樣做有什么好處呢梆暖?第一個好處就如上的第二條,第二個好處是加快圖片的加載速度掂骏,Fresco的加載圖片的流程為:查找Bitmap緩存中是否存在轰驳,存在則直接返回Bitmap直接使用,不存在則查找未解碼圖片的緩存,如果存在則進行Decode成Bitmap然后直接使用并加入Bitmap緩存中级解,如果未解碼圖片緩存中查找不到冒黑,則進行硬盤緩存的檢查,如有勤哗,則進行IO抡爹、轉化、解碼等一系列操作芒划,最后成Bitmap供我們直接使用冬竟,并把未解碼(Encode)的圖片加入未解碼圖片緩存,把Bitmap加入Bitmap緩存中民逼,如硬盤緩存中沒有泵殴,則進行Network操作下載圖片,然后加入到各個緩存中拼苍。

既然Fresco使用了三級緩存笑诅,而有兩級是內存緩存,所以當我們的App在后臺時或者在內存低的情況下在onLowMemory()方法中疮鲫,我們應該手動清除應用的內存緩存吆你,我們可以使用下面的方式:

    ImagePipeline imagePipeline = Fresco.getImagePipeline();
    //清空內存緩存(包括Bitmap緩存和未解碼圖片的緩存)
    imagePipeline.clearMemoryCaches();
    //清空硬盤緩存,一般在設置界面供用戶手動清理
    imagePipeline.clearDiskCaches();

    //同時清理內存緩存和硬盤緩存
    imagePipeline.clearCaches();

3.總結:
Picasso所能實現的功能俊犯,Glide都能做妇多,無非是所需的設置不同。但是Picasso體積比起Glide小太多如果項目中網絡請求本身用的就是okhttp或者retrofit(本質還是okhttp)燕侠,那么建議用Picasso者祖,體積會小很多(Square全家桶的干活)。Glide的好處是大型的圖片流贬循,比如gif咸包、Video桃序,如果你們是做美拍杖虾、愛拍這種視頻類應用,建議使用媒熊。
Fresco在5.0以下的內存優(yōu)化非常好奇适,代價就是體積也非常的大,按體積算Fresco>Glide>Picasso
不過在使用起來也有些不便(小建議:他只能用內置的一個ImageView來實現這些功能芦鳍,用起來比較麻煩嚷往,我們通常是根據Fresco自己改改,直接使用他的Bitmap層)

MemoryFile 可以用來測試共享內存

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末柠衅,一起剝皮案震驚了整個濱河市皮仁,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖贷祈,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趋急,死亡現場離奇詭異,居然都是意外死亡势誊,警方通過查閱死者的電腦和手機呜达,發(fā)現死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粟耻,“玉大人查近,你說我怎么就攤上這事〖访Γ” “怎么了霜威?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長饭玲。 經常有香客問我侥祭,道長,這世上最難降的妖魔是什么茄厘? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任矮冬,我火速辦了婚禮,結果婚禮上次哈,老公的妹妹穿的比我還像新娘胎署。我一直安慰自己,他們只是感情好窑滞,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布琼牧。 她就那樣靜靜地躺著,像睡著了一般哀卫。 火紅的嫁衣襯著肌膚如雪巨坊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天此改,我揣著相機與錄音趾撵,去河邊找鬼。 笑死共啃,一個胖子當著我的面吹牛占调,可吹牛的內容都是我干的。 我是一名探鬼主播移剪,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼究珊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了纵苛?” 一聲冷哼從身側響起剿涮,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤言津,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后取试,有當地人在樹林里發(fā)現了一具尸體纺念,經...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年想括,在試婚紗的時候發(fā)現自己被綠了陷谱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡瑟蜈,死狀恐怖烟逊,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情铺根,我是刑警寧澤宪躯,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站位迂,受9級特大地震影響访雪,放射性物質發(fā)生泄漏。R本人自食惡果不足惜掂林,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一臣缀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泻帮,春花似錦精置、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至元莫,卻和暖如春赖阻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踱蠢。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工火欧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人朽基。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓布隔,卻偏偏與公主長得像离陶,于是被迫代替她去往敵國和親稼虎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內容