1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
| public class LruBitmapPool implements BitmapPool { private static final String TAG = "LruBitmapPool"; private static final Bitmap.Config DEFAULT_CONFIG = Bitmap.Config.ARGB_8888;
private final LruPoolStrategy strategy; private final Set<Bitmap.Config> allowedConfigs; private final int initialMaxSize; private final BitmapTracker tracker;
private int maxSize; private int currentSize; private int hits; private int misses; private int puts; private int evictions;
LruBitmapPool(int maxSize, LruPoolStrategy strategy, Set<Bitmap.Config> allowedConfigs) { this.initialMaxSize = maxSize; this.maxSize = maxSize; this.strategy = strategy; this.allowedConfigs = allowedConfigs; this.tracker = new NullBitmapTracker(); }
* Constructor for LruBitmapPool. * * @param maxSize The initial maximum size of the pool in bytes. */ public LruBitmapPool(int maxSize) { this(maxSize, getDefaultStrategy(), getDefaultAllowedConfigs()); }
* Constructor for LruBitmapPool. * * @param maxSize The initial maximum size of the pool in bytes. * @param allowedConfigs A white listed set of {@link android.graphics.Bitmap.Config} that are allowed to be put * into the pool. Configs not in the allowed set will be rejected. */ public LruBitmapPool(int maxSize, Set<Bitmap.Config> allowedConfigs) { this(maxSize, getDefaultStrategy(), allowedConfigs); }
@Override public int getMaxSize() { return maxSize; }
@Override public synchronized void setSizeMultiplier(float sizeMultiplier) { maxSize = Math.round(initialMaxSize * sizeMultiplier); evict(); }
@Override public synchronized boolean put(Bitmap bitmap) { if (bitmap == null) { throw new NullPointerException("Bitmap must not be null"); } if (!bitmap.isMutable() || strategy.getSize(bitmap) > maxSize || !allowedConfigs.contains(bitmap.getConfig())) { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Reject bitmap from pool" + ", bitmap: " + strategy.logBitmap(bitmap) + ", is mutable: " + bitmap.isMutable() + ", is allowed config: " + allowedConfigs.contains(bitmap.getConfig())); } return false; }
final int size = strategy.getSize(bitmap); strategy.put(bitmap); tracker.add(bitmap);
puts++; currentSize += size;
if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Put bitmap in pool=" + strategy.logBitmap(bitmap)); } dump();
evict(); return true; }
private void evict() { trimToSize(maxSize); }
@Override public synchronized Bitmap get(int width, int height, Bitmap.Config config) { Bitmap result = getDirty(width, height, config); if (result != null) { result.eraseColor(Color.TRANSPARENT); }
return result; }
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @Override public synchronized Bitmap getDirty(int width, int height, Bitmap.Config config) { final Bitmap result = strategy.get(width, height, config != null ? config : DEFAULT_CONFIG); if (result == null) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "Missing bitmap=" + strategy.logBitmap(width, height, config)); } misses++; } else { hits++; currentSize -= strategy.getSize(result); tracker.remove(result); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { result.setHasAlpha(true); } } if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Get bitmap=" + strategy.logBitmap(width, height, config)); } dump();
return result; }
@Override public void clearMemory() { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "clearMemory"); } trimToSize(0); }
@SuppressLint("InlinedApi") @Override public void trimMemory(int level) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "trimMemory, level=" + level); } if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE) { clearMemory(); } else if (level >= android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) { trimToSize(maxSize / 2); } } }
|