使用Picasso加載圖片的內存優化實踐

0 說明

如今Android開源庫中有許多圖片加載框架,本文以picasso爲例,總結下開發過程當中的一些優化經驗,使用的picasso版本以下java

compile 'com.squareup.picasso:picasso:2.5.2'

1 圖片裁剪

在列表頁儘可能使用裁剪後的圖片,在查看大圖模式下才加載完整的圖片。android

圖片裁剪示例git

Picasso.with( imageView.getContext() )
.load(url)
.resize(dp2px(250),dp2px(250))
.centerCrop()
.into(imageView);

picasso默認狀況下會使用全局的ApplicationContext,即開發者傳進去Activity,picasso也會經過activity獲取ApplicationContext。github

2 查看大圖放棄memory cache

Picasso默認會使用設備的15%的內存做爲內存圖片緩存,且現有的api沒法清空內存緩存。咱們能夠在查看大圖時放棄使用內存緩存,圖片從網絡下載完成後會緩存到磁盤中,加載會從磁盤中加載,這樣能夠加速內存的回收。api

Picasso.with(getApplication())
.load(mURL)
.memoryPolicy(NO_CACHE, NO_STORE)
.into(imageView);

其中memoryPolicy的NO_CACHE是指圖片加載時放棄在內存緩存中查找,NO_STORE是指圖片加載完不緩存在內存中。緩存

3 RecyclableImageView

重寫ImageView的onDetachedFromWindow方法,在它從屏幕中消失時回調,去掉drawable引用,能加快內存的回收。bash

public class RecyclerImageView extends ImageView{ 
    ...    @Override    
    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();
        setImageDrawable(null);   
    }
}

實驗環境:加載大圖不使用內存緩存。
實驗場景:從圖片列表頁切換到詳情頁看大圖,而後返回,不停重複。網絡


普通ImageView框架


RecyclableImageViewide

能夠看到使用了RecyclableImageView的實驗在切換過程當中產生的內存谷值明顯優於ImageView,說明drawable更容易被回收。

4 新進程中查看大圖

列表頁的內存已經很是穩定,可是查看大圖時,大圖每每佔用了20+m內存,加上現有進程中的內存,很是容易oom,在新進程中打開Activity成爲比較取巧的避免oom的方式。

<activity android:name=".DetailActivity" android:process=":picture"/>

只要在AndroidManifest.xml中定義Activity時加入process屬性,便可在新進程中打開此Activity。由此,picasso也將在新進程中建立基於新ApplicationContext的單例。

5 列表頁滑動優化

picasso能夠對多個加載請求設置相同的tag,即

Object tag = new Object();
Picasso.with( imageView.getContext() )
.load(url)
.resize(dp2px(250),dp2px(250))
.centerCrop()
.tag(tag)
.into(imageView);

例如在RecyclerView滑動時監聽,處理不一樣的表現:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState)
    {        if (newState == RecyclerView.SCROLL_STATE_IDLE)
        {
            Picasso.with(context).resumeTag(tag);
        }        else
        {
            Picasso.with(context).pauseTag(tag);
        }
    }
});

6 RGB_565

對於不透明的圖片可使用RGB_565來優化內存。

Picasso.with( imageView.getContext() )
.load(url)
.config(Bitmap.Config.RGB_565)
.into(imageView);

默認狀況下,Android使用ARGB_8888

Android中有四種,分別是:
ALPHA_8:每一個像素佔用1byte內存
ARGB_4444:每一個像素佔用2byte內存
ARGB_8888:每一個像素佔用4byte內存
RGB_565:每一個像素佔用2byte內存

RGB_565呈現結果與ARGB_8888接近,內存對好比下圖


默認ARGB_8888,列表滑動時平均內存10m


RGB_565,列表滑動時,平均7M

7 reference

Picasso and Context
JakeWharton的避免OOM建議
Clear Cache memory of Picasso



文/我是Asha(簡書做者)原文連接:http://www.jianshu.com/p/6b746c904a49著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。

相關文章
相關標籤/搜索