2014-06-22 71 views
1

我正在處理多達1200個圖像。我通過在此處發現的以前的問題的幫助將其優化爲從100張圖像到500張圖像。現在,這是我所:Android BitmapFactory.decodeFile放慢速度直到內存不足

public Bitmap getBitmap(String filepath) { 
     boolean done = false; 
     int downsampleBy = 2; 
     Bitmap bitmap = null; 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(filepath, options); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     options.inPreferredConfig = Config.RGB_565; 
     while (!done) { 
      options.inSampleSize = downsampleBy++; 
      try { 
       bitmap = BitmapFactory.decodeFile(filepath, options); 
       done = true; 
      } catch (OutOfMemoryError e) { 
       // Ignore. Try again. 
      } 
     } 
     return bitmap; 
    } 

該功能被稱爲一個循環中,它也快,直到達到第500個圖像。此時它會放慢速度,直到最終停止在第600張圖像附近工作。

在這一點上,我不知道如何優化它,使其工作。你認爲發生了什麼,我該如何解決它?

編輯

  // Decode BItmap considering memory limitations 
    public Bitmap getBitmap(String filepath) { 
     Bitmap bitmap = null; 
     BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(filepath, options); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     options.inPreferredConfig = Config.RGB_565; 
     options.inDither = true; 
     options.inSampleSize= calculateInSampleSize(options, 160, 120); 

     return bitmap = BitmapFactory.decodeFile(filepath, options); 
    } 

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

取得了公認的答案的變化。使用Google教程中的函數來獲取正確的樣本大小。在清單中添加largeHeap,並在遍歷所有圖像之前調用System.gc()一次。

+0

我不知道這是否是一個可怕的計劃,但你有沒有嘗試過調用System.gc()來防止內存不足? – EpicPandaForce

+0

@Zhuinden我沒有,我應該在哪裏調用? – apSTRK

回答

2

首先,你永遠不應該期望捕獲一個錯誤。這裏描述:Java documentationAn Error是Throwable的一個子類,它指示合理的應用程序不應該嘗試捕獲的嚴重問題。

有大約裝載位圖一些幫助:Android Developers | Loading large bitmaps

可以通過聲明在你的應用程序清單的largeHeap="true"屬性得到一些更多的內存。

而且System.gc()調用可能有助於釋放一些未使用的內存,但我不會真的依賴那個調用。

+0

我在StackOverflow答案中找到它之後做了這個。我在我看來似乎不是正確的方法,但它比這個問題的caculateInSampleSize函數更好:http://stackoverflow.com/questions/21392972/how-to-load-large-images-in -android-and-avoid-memory-error- 我將嘗試更改largeHeap屬性和System.gc()調用,看看它是否有用@Sipka – apSTRK

+0

通過添加largeHeap並調用System.gc( )我得到它處理788圖像1200.所以它確實幫助,但它墜毀在788 – apSTRK

+0

你可以嘗試每次調用'System.gc()'在你試圖加載圖像之前。垃圾收集器將嘗試釋放盡可能多的內存,包括之前回收的位圖。 – Sipka