如Fresco 中文官網所述,Fresco是專為Android加載圖片的框架,但是使用不當也會遇到很多坑,下面根據自己親身踩坑的經歷談談 Android中使用fresco加載大量圖片出現的OOM問題。
關于Fresco的簡單使用如下,下面的博客介紹的非常詳細了,可以仔細閱讀一下。
此處我就直接了當簡單介紹Fresco加載圖片使用步驟及遇到OOM的應對策略。
本人使用Fresco加載圖片列表發生OOM解決思路:
首先分頁加載
1,加載圖片高清,圖片太大。方法:初始化時對圖片進行壓縮, 和ImageRequest的ResizeOptions一起使用,作用就是在圖片解碼時根據ResizeOptions所設的寬高的像素進行解碼,這樣解碼出來可以得到一個更小的Bitmap。
.setDownsampleEnabled(true)
.setResizeAndRotateEnabledForNetwork(true) // 對網絡圖片進行resize處理,減少內存消耗
2,修改圖片默認格式
????? 因為Fresco默認圖片格式是RGB_8888,這就對內存占用很高,所以可以用內存開銷低一些的配置方式,比如:RGB_4444、RGB_565;
.setBitmapsConfig(Bitmap.Config.RGB_565)
3,指定圖片加載尺寸,這里我直接貼上封裝在RecyclerCommonAdapter中圖片加載方法代碼(可以換成自己的方式):
public RecyclerViewHolder setFrescoImg(int viewId, Uri uri){
SimpleDraweeView simpleDraweeView = getView(viewId);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
//指定寬高尺寸
.setResizeOptions(new ResizeOptions(
DisplayUtil.dp2px(mContext,360),DisplayUtil.dp2px(mContext,200)))
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(simpleDraweeView.getController())
.build();
simpleDraweeView.setController(controller);
return this;
}
完整代碼
a,在項目Application里調用Fresco.initialize(this)完成初始化。
public class MyApplication extends Application{
@Overridepublic void onCreate() {
super.onCreate();
initFresco();
}
private void initFresco() {
//對ImagePipelineConfig進行一些配置
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(getApplicationContext())
.setDownsampleEnabled(true)? ? ? ? ? ? ? ? ? ? ? ? ? ?? // 對圖片進行自動縮放
setResizeAndRotateEnabledForNetwork(true)?? // 對網絡圖片進行resize處理,減少內存消耗
.setBitmapsConfig(Bitmap.Config.RGB_565)??? //圖片設置RGB_565,減小內存開銷? fresco默認情況下是RGB_8888
.build();
Fresco.initialize(this, config);
}
}
b,根據View的尺寸進行縮放圖片(ResizeOptions),我是在recyclerView中加載圖片,所以方法寫在RecyclerViewHolder中了:
public RecyclerViewHolder setFrescoImg(int viewId, Uri uri){
SimpleDraweeView simpleDraweeView = getView(viewId);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
???????????????????????????????????????? .setResizeOptions(new ResizeOptions( DisplayUtil.dp2px(mContext,360),DisplayUtil.dp2px(mContext,200)))
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(simpleDraweeView.getController())
.build();
simpleDraweeView.setController(controller);
return this;
}
另外貼上DisplayUtil工具類dp轉px方法
public class DisplayUtil{
public static int dp2px(Context context, float dipValue) {
????????? final float scale = context.getResources().getDisplayMetrics().density;
???????? return (int) (dipValue * scale + 0.5f);
}
}
c,圖片加載使用
直接調用方法就可以了,
eg:holder.setFrescoImg(R.id.video_img,Uri.parse(item.getposter));
如上,item.getPoster()就是服務端返回的圖片數據;本人項目中這樣的寫基本很少出現OOM了。