内存不足使用 BitmapDrawable 时出错



>我下载并保留了我应用程序中的照片列表:

List<BitmapDrawable> photos = new ArrayList<BitmapDrawable>();
photos.add(Utils.bitmapToBitmapDrawable(downloadBitmap(s));
public static Bitmap downloadBitmap(String url) {
    // GET input stream from server
    return BitmapFactory.decodeStream(inputStream);
}

正在尝试解除分配:

if (dldedPics.get(0).getPhotos() != null && !dldedPics.get(0).getPhotos().isEmpty()) {
    for (BitmapDrawable b : dldedPics.get(0).getPhotos()) {
        b.getBitmap().recycle();
    }
}
dldedPics.get(0).setPhotos(null);
Runtime.getRuntime().gc();

我似乎无法正确解除分配它们,因为在 10-20 张 100kb 照片之后,我很快就得到了一个 OutOfMemoryError(在解码流行)。

堆栈跟踪:

11-23 09:43:07.861: E/AndroidRuntime(3079): FATAL EXCEPTION: AsyncTask #1
11-23 09:43:07.861: E/AndroidRuntime(3079): java.lang.RuntimeException: An error occured while executing doInBackground()
11-23 09:43:07.861: E/AndroidRuntime(3079):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.lang.Thread.run(Thread.java:1096)
11-23 09:43:07.861: E/AndroidRuntime(3079): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget
11-23 09:43:07.861: E/AndroidRuntime(3079):     at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:459)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:515)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at com.domain.persistence.Utils.downloadBitmap(Utils.java:385)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at com.domain.service.tasks.AllPhotosDownloaderTask.doInBackground(AllPhotosDownloaderTask.java:51)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at com.domain.service.tasks.AllPhotosDownloaderTask.doInBackground(AllPhotosDownloaderTask.java:1)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
11-23 09:43:07.861: E/AndroidRuntime(3079):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-23 09:43:07.861: E/AndroidRuntime(3079):     ... 4 more
11-23 09:43:08.201: E/dalvikvm-heap(3079): 240000-byte external allocation too large for this process.
11-23 09:43:08.231: E/GraphicsJNI(3079): VM won't let us allocate 240000 bytes

您应该只加载所需的图像大小,而不是整个图像。

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = scale;
        b = BitmapFactory.decodeStream(inputStream, null, options);

从 http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

如果设置为值> 1,则请求解码器对原始图像进行子采样,返回较小的图像以节省内存。样本大小是任一维度中对应于解码位图中单个像素的像素数。例如,inSampleSize == 4 返回的图像宽度/高度为原始图像的宽度/高度的 1/4,像素数的 1/16。

最新更新