BitmapPool.java revision cafd30f96355ad446943d60cd2595d08423944e2
1// Copyright 2012 Google Inc. All Rights Reserved. 2 3package com.android.gallery3d.data; 4 5import android.graphics.Bitmap; 6import android.graphics.BitmapFactory; 7import android.graphics.BitmapFactory.Options; 8 9import com.android.gallery3d.ui.Log; 10import com.android.gallery3d.util.ThreadPool.JobContext; 11 12import java.io.FileDescriptor; 13import java.util.ArrayList; 14 15public class BitmapPool { 16 private static final String TAG = "BitmapPool"; 17 18 private static final int POOL_SIZE = 16; 19 private final ArrayList<Bitmap> mPool = new ArrayList<Bitmap>(POOL_SIZE); 20 21 private final int mWidth; 22 private final int mHeight; 23 24 public BitmapPool(int width, int height) { 25 mWidth = width; 26 mHeight = height; 27 } 28 29 public synchronized Bitmap getBitmap() { 30 int size = mPool.size(); 31 return size > 0 ? mPool.remove(size - 1) : null; 32 } 33 34 public void recycle(Bitmap bitmap) { 35 if (bitmap == null) return; 36 if ((bitmap.getWidth() != mWidth) || (bitmap.getHeight() != mHeight)) { 37 bitmap.recycle(); 38 return; 39 } 40 synchronized (this) { 41 if (mPool.size() < POOL_SIZE) mPool.add(bitmap); 42 } 43 } 44 45 public synchronized void clear() { 46 mPool.clear(); 47 } 48 49 public Bitmap decode(JobContext jc, 50 byte[] data, int offset, int length, BitmapFactory.Options options) { 51 if (options == null) options = new BitmapFactory.Options(); 52 if (options.inSampleSize < 1) options.inSampleSize = 1; 53 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 54 options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null; 55 try { 56 Bitmap bitmap = DecodeUtils.decode(jc, data, offset, length, options); 57 if (options.inBitmap != null && options.inBitmap != bitmap) { 58 recycle(options.inBitmap); 59 options.inBitmap = null; 60 } 61 return bitmap; 62 } catch (IllegalArgumentException e) { 63 if (options.inBitmap == null) throw e; 64 65 Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap"); 66 recycle(options.inBitmap); 67 options.inBitmap = null; 68 return DecodeUtils.decode(jc, data, offset, length, options); 69 } 70 } 71 72 // This is the same as the method above except the source data comes 73 // from a file descriptor instead of a byte array. 74 public Bitmap decode(JobContext jc, 75 FileDescriptor fileDescriptor, Options options) { 76 if (options == null) options = new BitmapFactory.Options(); 77 if (options.inSampleSize < 1) options.inSampleSize = 1; 78 options.inPreferredConfig = Bitmap.Config.ARGB_8888; 79 options.inBitmap = (options.inSampleSize == 1) ? getBitmap() : null; 80 try { 81 Bitmap bitmap = DecodeUtils.decode(jc, fileDescriptor, options); 82 if (options.inBitmap != null&& options.inBitmap != bitmap) { 83 recycle(options.inBitmap); 84 options.inBitmap = null; 85 } 86 return bitmap; 87 } catch (IllegalArgumentException e) { 88 if (options.inBitmap == null) throw e; 89 90 Log.w(TAG, "decode fail with a given bitmap, try decode to a new bitmap"); 91 recycle(options.inBitmap); 92 options.inBitmap = null; 93 return DecodeUtils.decode(jc, fileDescriptor, options); 94 } 95 } 96} 97