当前位置: 代码迷 >> Android >> android使用lrucache与softReference对图片进展优化
  详细解决方案

android使用lrucache与softReference对图片进展优化

热度:92   发布时间:2016-04-28 04:44:34.0
android使用lrucache与softReference对图片进行优化
⑴强引用(StrongReference)   Person p=new Person();
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
 
⑵软引用(SoftReference
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。

⑶弱引用(WeakReference
弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

 
⑷虚引用(PhantomReference
虚引用顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
SoftReference<String> srf = new SoftReference<String>("a");

String string = srf.get(); 

使用软引用以后,在OutOfMemory异常发生之前,这些缓存的图片资源的内存空间可以被释放掉的,从而避免内存达到上限,避免Crash发生。

private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

 

public void addBitmapToCache(String path) {

        // 强引用的Bitmap对象

        Bitmap bitmap = BitmapFactory.decodeFile(path);

        // 软引用的Bitmap对象

        SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap);

        // 添加该对象到Map中使其缓存

        imageCache.put(path, softBitmap);

    }


public Bitmap getBitmapByPath(String path) {

        // 从缓存中取软引用的Bitmap对象

        SoftReference<Bitmap> softBitmap = imageCache.get(path);

        // 判断是否存在软引用

        if (softBitmap == null) {

            return null;

        }

        // 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空

        Bitmap bitmap = softBitmap.get();

        if(bitmap==null){

            return null;

        }

       return bitmap;

    }



2 LruCache     
LruCache,这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。

private LruCache<String, Bitmap> mMemoryCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
 // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
 // LruCache通过构造函数传入缓存值
 int maxMemory = (int) (Runtime.getRuntime().maxMemory() );
 // 使用最大可用内存值的1/8作为缓存的大小。
 int cacheSize = maxMemory / 8;
 mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
  @Override
  protected int sizeOf(String key, Bitmap bitmap) {
   // 重写此方法来衡量每张图片的大小
   return bitmap.getByteCount();
  }
 };
}

/**2种情况:
  *1.当有条目被挤出时,evicted 为true, key与oldValue 为被挤出的条目的值
  *2.有条目值发生改变时,evicted 为false ,使用put()替换值
  *  key 为替换条目的key oldValue为条目之前的值  newValue 为条目的新值
  *  使用remove()时, key与oldValue 为被移除的条目
  */
@Override 
protected void entryRemoved(boolean evicted, String key, 
     Bitmap oldValue, Bitmap newValue) { 

    System.out.println("evicted:" + evicted + "key:" + key 
      + "oldValue:" + oldValue + "newValue:" + newValue); 
}


public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
 if (getBitmapFromMemCache(key) == null) {
  mMemoryCache.put(key, bitmap);
 }
}
public Bitmap getBitmapFromMemCache(String key) {
 return mMemoryCache.get(key);
}

public Bitmap removeBitmapFromMemCache(String key) {
 return mMemoryCache.remove(key);
}




volley中使用:
//初始化imageloader

ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new ImageCache() {
   @Override
   public void putBitmap(String url, Bitmap bitmap) {
    mLruCacheManager.putBitmap(url, bitmap);
   }
   @Override
   public Bitmap getBitmap(String url) {
    return mLruCacheManager.getBitmap(url);
   }
  });
//对相应的imageview进行图片的设置
imageView.setImageUrl(url ,imageloader);
url  :图片资源的网络url
imageLoader: 相对应的ImageLoader 
1.配置lrucache的缓存设置
2.配置SoftReference的缓存设置
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class LruCacheManager {
 private static LruCacheManager lruCacheManager;
 private SoftReferenceCacheManager softReferenceCacheManager;
 private LruCache<String, Bitmap> lruCache;
 // 配置一级缓存设置LruCache
 private LruCacheManager() {
  // (Runtime.getRuntime().maxMemory()运行时系统所分配的内存资源
  lruCache = new LruCache<String, Bitmap>((int) (Runtime.getRuntime()
    .maxMemory() / 8)) {
   @Override
   protected int sizeOf(String key, Bitmap value) {
    if (value != null) {
     return value.getRowBytes() * value.getHeight();
    }
    return 0;
   }
   // 当内存资源不足是进行调用
   @Override
   protected void entryRemoved(boolean evicted, String key,
     Bitmap oldValue, Bitmap newValue) {
    if (evicted) {
     // 放到软引用当中
     softReferenceCacheManager.put(key, oldValue);
    }
   }
  };
  // 初始化softRefrenceCacheManager
  softReferenceCacheManager = SoftReferenceCacheManager
    .getSoftReferenceCacheManager();
 }
 // 初始化LruCachaManager操作
 public static LruCacheManager getLruCacheManager() {
  if (lruCacheManager == null) {
   lruCacheManager = new LruCacheManager();
  }
  return lruCacheManager;
 }
 // 将图片添加到lrucache中
 public void putBitmap(String url, Bitmap bm) {
  lruCache.put(url, bm);
 }
 // 从lrucache中取出图片
 public Bitmap getBitmap(String url) {
  Bitmap bm = null;
  bm = lruCache.get(url);
  if (bm == null) {
   // 软引用当中取
   bm = softReferenceCacheManager.get(url);
   // 将从软引用中取出的图片添加到lrucache中,并将软引用中的删除掉
   if (bm != null) {
    lruCache.put(url, bm);
    softReferenceCacheManager.remove(url);
   }
  }
  return bm;
 }
package com.example.volley04;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;
public class SoftReferenceCacheManager {
 private static SoftReferenceCacheManager softReferenceCacheManager;
 private final Map<String, SoftReference<Bitmap>> map;
 // 单例模式
 private SoftReferenceCacheManager() {
  map = new HashMap<String, SoftReference<Bitmap>>();
 }
 // 初始化对象的操作
 public static SoftReferenceCacheManager getSoftReferenceCacheManager() {
  if (softReferenceCacheManager == null) {
   softReferenceCacheManager = new SoftReferenceCacheManager();
  }
  return softReferenceCacheManager;
 }
 // 将图片添加到软引用中
 public void put(String url, Bitmap bm) {
  SoftReference<Bitmap> soft = new SoftReference<Bitmap>(bm);
  map.put(url, soft);
 }
 // 从软引用中取出图片
 public Bitmap get(String url) {
  Bitmap bm = null;
  SoftReference<Bitmap> soft = map.get(url);
  if (soft != null) {
   bm = soft.get();
  }
  return bm;
 }
 // 将图片在软引用中删除
 public void remove(String url) {
  map.remove(url);
 }
}





  相关解决方案