0

アプリケーションに写真のリストをダウンロードして保持します。

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(decodeStream行で)がかなり早く発生するため、適切に割り当てを解除できないようです。

スタックトレース:

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
4

2 に答える 2

0

ビットマップを使用したサンプル実装については、以下のリンクを参照してください。

https://github.com/nostra13/Android-Universal-Image-Loader

于 2012-11-23T10:23:16.673 に答える
0

画像全体ではなく、必要な画像サイズのみをロードする必要があります。

        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 より大きい値に設定すると、メモリを節約するために小さいイメージを返し、元のイメージをサブサンプリングするようにデコーダに要求します。サンプル サイズは、デコードされたビットマップ内の 1 つのピクセルに対応する、いずれかの次元のピクセル数です。たとえば、inSampleSize == 4 は、元の幅/高さが 1/4、ピクセル数が 1/16 のイメージを返します。

于 2012-11-23T10:48:51.977 に答える