2011-02-09 52 views
3

我的應用程序正在使用位圖,每當用戶第二次停止工作時都會到達顯示圖像的特定活動。Android - 如何避免使用位圖的內存過載?

Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"//Pics/"Image.jpg"); 

我一直在使用的東西就像試圖...

BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inTempStorage = new byte[16*1024]; 

不知道如何設置它。但是這沒有幫助。一旦用戶離開這個活動,是不是有辦法清除位圖等?謝謝

回答

8

除了使用Bitmap.recycle()的建議(這是不是適用於所有情況,它是在頸部疼痛被問:「我還需要此位圖」),我一直用這個技術,它的作品真的罰款:

// 1. create a cache map 
private WeakHashMap<String, SoftReference<Bitmap>> mCache; 

正如你所看到的,它的WeakReference s的一個SoftReference爲值的哈希映射。

//2. when you need a bitmap, ask for it: 
public Bitmap get(String key){ 
    if(key == null){ 
     return null; 
    } 
    if(mCache.containsKey(key)){ 
     SoftReference<Bitmap> reference = mCache.get(key); 
     Bitmap bitmap = reference.get(); 
     if(bitmap != null){ 
      return bitmap; 
     } 
     return decodeFile(key); 
    } 
    // the key does not exists so it could be that the 
    // file is not downloaded or decoded yet... 
    File file = new File(Environment.getExternalStorageDirectory(), key); 
    if(file.exists()){ 
     return decodeFile(key); 
    } else{ 
     throw new RuntimeException("Boooom!"); 
    } 
} 

這將檢查緩存映射。如果文件已經被解碼,它將被返回;否則它將被解碼和緩存。

//3. the decode file will look like this in your case 
private Bitmap decodeFile(String key) { 
    Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"//Pics/"+key); 
    mCache.put(key, new SoftReference<Bitmap>(bitmap)); 
    return bitmap; 
} 

使用軟引用是很好的,因爲您將位圖從內存中移除到操作系統的責任。

+0

畢竟這些年來,你還在使用這種方法嗎?如果是這樣,請告訴您爲什麼在已經有WeakHashMap的情況下仍然使用SoftReference? – frankish 2015-02-17 12:29:34

1

請注意。 當我們考慮softreferences時,我們認爲操作系統會在報告超出內存異常之前從memrory中刪除softreferenced對象。

在android中並不總是如此。我必須實現我自己的圖像緩存系統,並且我可以保證當內存幾乎滿時,軟引用的對象不會從內存中移除。

最後,我不得不切換到硬引用(正常的),但使用android.support.v4.util.LruCache管理緩存的對象。我會從lru緩存中的onRemoved回調調用回收。其定義更方便。

乾杯。