尚拙

一个分享技术、学习成长的个人博客网站

0%

Picasso 加载图片之内存优化

目前主要的图片加载框架有Picasso、Glide、Fresco等,本文以Picasso为例,总结一些图片加载的内存优化问题。

1、裁减图片

在列表页尽量使用裁剪后的图片,在查看大图模式下才加载完整的图片。

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

2、加载大图不使用memory cache

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

3、重写ImageView加速内存回收

重写ImageView的onDetachedFromWindow方法,在它从屏幕中消失时回调,去掉drawable引用,能加快内存的回收。

public class RecyclerImageView extends ImageView
{
...

@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setImageDrawable(null);
}
}

4、新进程中查看大图

列表页的内存已经非常稳定,但是查看大图时,大图往往占用了20+m内存,加上现有进程中的内存,非常容易oom,在新进程中打开Activity成为比较取巧的避免oom的方式。只要在AndroidManifest.xml中定义Activity时加入process属性,即可在新进程中打开此Activity。由此,picasso也将在新进程中创建基于新ApplicationContext的单例。

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

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、降低图片质量

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内存