您的位置:首页 > 理论基础 > 计算机网络

android加载网络图片时有效避免OOM

2016-03-30 16:58 525 查看
最近公司开发需要加载大量图片,遇到了OOM问题,在几经周折后终于解决了这个问题。我项目的网络框架使用的封装的okhttp,okhttp的底层封装的Volly,在这里面封装了一个方法加载网络图片,不过效果不理想,在Listview或者recyclerView中使用时会偶尔出现图片错位的情况,我刚开始时配合LruCahe缓存使用,效果并不好,而且在不分页的情况下,一页加载的图片过多时加载速度很不理想。于是改用其他方法,使用了原生控件NetworkImage。废话不多说,在开始前,你需要导入Volly 的jar包。直接上代码
public static void setNetImgWork(RequestQueue mQueue,Context context, NetworkImageView view, String url, int defaultImg) {
LruImageCache lruImageCache = LruImageCache.instance();
com.android.volley.toolbox.ImageLoader loader = new com.android.volley.toolbox.ImageLoader(mQueue, lruImageCache);// 创建一个ImageLoader
view.setDefaultImageResId(defaultImg);
view.setErrorImageResId(R.drawable.icon_error);
view.setImageUrl(url, loader);
}
  我对加载图片的方法 封装在了一个图片工具类里面,需要五个参数,分别是RequestQueue对象,context对象,NetworkImage控件,地址,默认图片。参数没什么说的。这里我也遇到了一个问题
public static void setNetImgWork(Context context, NetworkImageView view, String url, int defaultImg) {
RequestQueue mQueue = Volly.newRequest(context);    
LruImageCache lruImageCache = LruImageCache.instance();
com.android.volley.toolbox.ImageLoader loader = new com.android.volley.toolbox.ImageLoader(mQueue, 	lruImageCache);// 创建一个ImageLoader
view.setDefaultImageResId(defaultImg);
view.setErrorImageResId(R.drawable.icon_error);
view.setImageUrl(url, loader);
}
刚开始我的方法是这样写的,这样就存在一个问题每次使用这个方法的时候都会去new一个RequestQueue 对象,如果一个listView一页有20条记录,那么这个对象就被创建了20个。RequestQueue我的理解就相当于一个网络连接的线程,具体的可以看看这篇博客http://www.cnblogs.com/android100/p/Android-Volley5.html。当这个对象创建多了就会报OOM异常。所以我的解决办法就是在使用的activity中去创建RequestQueue对象,在使用的时候直接把这个对象传递就可以了
最后贴出LruImageCache 这个类
public class LruImageCache implements ImageCache {

private static LruCache<String, Bitmap> mMemoryCache;

private static LruImageCache lruImageCache;

private LruImageCache() {
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes() * bitmap.getHeight();
}
};
}

public static LruImageCache instance() {
if (lruImageCache == null) {
lruImageCache = new LruImageCache();
}
return lruImageCache;
}

@Override
public Bitmap getBitmap(String arg0) {
return mMemoryCache.get(arg0);
}

@Override
public void putBitmap(String arg0, Bitmap arg1) {
if (arg0 != null ) {
if (getBitmap(arg0) == null) {
mMemoryCache.put(arg0, arg1);
} else {
Log.e("缓存图片通知", "没有缓存图片");
}
} else {
Log.e("缓存图片通知", "缓存的KEY为空");
}
}

}
刚工作没多久,这是工作中遇到的问题,希望能对遇到同样问题的你,有所帮助。如果我的解决办法有什么问题,希望大家能指点一下。
8766
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息