提交 3422c575 编写于 作者: S Sam Judd

Whitelist bitmap configurations in LruBitmapPool.

Fixes #301.
上级 7fb36016
......@@ -23,20 +23,23 @@ import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowBitmap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE, emulateSdk = 18)
public class LruBitmapPoolTest {
private static final int MAX_SIZE = 10;
private static final Set<Bitmap.Config> ALLOWED_CONFIGS = Collections.singleton(Bitmap.Config.ARGB_8888);
private MockStrategy strategy;
private LruBitmapPool pool;
@Before
public void setUp() throws Exception {
strategy = new MockStrategy();
pool = new LruBitmapPool(MAX_SIZE, strategy);
pool = new LruBitmapPool(MAX_SIZE, strategy, ALLOWED_CONFIGS);
}
@Test
......@@ -68,7 +71,7 @@ public class LruBitmapPoolTest {
return 4;
}
};
pool = new LruBitmapPool(3, strategy);
pool = new LruBitmapPool(3, strategy, ALLOWED_CONFIGS);
pool.put(createMutableBitmap());
assertEquals(0, strategy.numRemoves);
assertEquals(0, strategy.numPuts);
......@@ -117,7 +120,7 @@ public class LruBitmapPoolTest {
@Test
public void testPassesArgb888ToStrategyAsConfigForRequestsWithNullConfigsOnGet() {
LruPoolStrategy strategy = mock(LruPoolStrategy.class);
LruBitmapPool pool = new LruBitmapPool(100, strategy);
LruBitmapPool pool = new LruBitmapPool(100, strategy, ALLOWED_CONFIGS);
Bitmap expected = createMutableBitmap();
when(strategy.get(anyInt(), anyInt(), eq(Bitmap.Config.ARGB_8888))).thenReturn(expected);
......@@ -129,7 +132,7 @@ public class LruBitmapPoolTest {
@Test
public void testPassesArgb8888ToStrategyAsConfigForRequestsWithNullConfigsOnGetDirty() {
LruPoolStrategy strategy = mock(LruPoolStrategy.class);
LruBitmapPool pool = new LruBitmapPool(100, strategy);
LruBitmapPool pool = new LruBitmapPool(100, strategy, ALLOWED_CONFIGS);
Bitmap expected = createMutableBitmap();
when(strategy.get(anyInt(), anyInt(), eq(Bitmap.Config.ARGB_8888))).thenReturn(expected);
......@@ -140,7 +143,7 @@ public class LruBitmapPoolTest {
private void testTrimMemory(int fillSize, int trimLevel, int expectedSize) {
MockStrategy strategy = new MockStrategy();
LruBitmapPool pool = new LruBitmapPool(MAX_SIZE, strategy);
LruBitmapPool pool = new LruBitmapPool(MAX_SIZE, strategy, ALLOWED_CONFIGS);
fillPool(pool, fillSize);
pool.trimMemory(trimLevel);
assertEquals("Failed level=" + trimLevel, expectedSize, strategy.numRemoves);
......@@ -188,6 +191,28 @@ public class LruBitmapPoolTest {
assertEquals(2 * MAX_SIZE, pool.getMaxSize());
}
@Test
public void testBitmapsWithDisallowedConfigsAreIgnored() {
pool = new LruBitmapPool(100, strategy, Collections.singleton(Bitmap.Config.ARGB_4444));
Bitmap bitmap = createMutableBitmap(Bitmap.Config.RGB_565);
pool.put(bitmap);
assertEquals(0, strategy.numPuts);
}
@Test
public void testBitmapsWithAllowedNullConfigsAreAllowed() {
pool = new LruBitmapPool(100, strategy, Collections.<Bitmap.Config>singleton(null));
Bitmap bitmap = createMutableBitmap();
Robolectric.shadowOf(bitmap).setConfig(null);
pool.put(bitmap);
assertEquals(1, strategy.numPuts);
}
private void fillPool(LruBitmapPool pool, int fillCount) {
for (int i = 0; i < fillCount; i++) {
pool.put(createMutableBitmap());
......@@ -195,9 +220,14 @@ public class LruBitmapPoolTest {
}
private Bitmap createMutableBitmap() {
Bitmap bitmap = ShadowBitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
return createMutableBitmap(Bitmap.Config.ARGB_8888);
}
private Bitmap createMutableBitmap(Bitmap.Config config) {
Bitmap bitmap = ShadowBitmap.createBitmap(100, 100, config);
Robolectric.shadowOf(bitmap).setMutable(true);
return bitmap;
}
private static class MockStrategy implements LruPoolStrategy {
......
package com.bumptech.glide;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.Log;
......@@ -16,6 +17,7 @@ import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
import com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
/**
......@@ -186,7 +188,12 @@ public class GlideBuilder {
MemorySizeCalculator calculator = new MemorySizeCalculator(context);
if (bitmapPool == null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
bitmapPool = new LruBitmapPool(calculator.getBitmapPoolSize());
int size = calculator.getBitmapPoolSize();
if (DecodeFormat.REQUIRE_ARGB_8888) {
bitmapPool = new LruBitmapPool(size, Collections.singleton(Bitmap.Config.ARGB_8888));
} else {
bitmapPool = new LruBitmapPool(size);
}
} else {
bitmapPool = new BitmapPoolAdapter();
}
......
......@@ -7,6 +7,7 @@ import android.graphics.Color;
import android.os.Build;
import android.util.Log;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
......@@ -22,6 +23,7 @@ public class LruBitmapPool implements BitmapPool {
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;
......@@ -33,10 +35,11 @@ public class LruBitmapPool implements BitmapPool {
private int evictions;
// Exposed for testing only.
LruBitmapPool(int maxSize, LruPoolStrategy strategy) {
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();
}
......@@ -46,7 +49,18 @@ public class LruBitmapPool implements BitmapPool {
* @param maxSize The initial maximum size of the pool in bytes.
*/
public LruBitmapPool(int maxSize) {
this(maxSize, getDefaultStrategy());
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
......@@ -62,10 +76,15 @@ public class LruBitmapPool implements BitmapPool {
@Override
public synchronized boolean put(Bitmap bitmap) {
if (!bitmap.isMutable() || strategy.getSize(bitmap) > maxSize) {
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=" + strategy.logBitmap(bitmap) + " is mutable="
+ bitmap.isMutable());
Log.v(TAG, "Reject bitmap from pool"
+ ", bitmap: " + strategy.logBitmap(bitmap)
+ ", is mutable: " + bitmap.isMutable()
+ ", is allowed config: " + allowedConfigs.contains(bitmap.getConfig()));
}
return false;
}
......@@ -176,6 +195,15 @@ public class LruBitmapPool implements BitmapPool {
return strategy;
}
private static Set<Bitmap.Config> getDefaultAllowedConfigs() {
Set<Bitmap.Config> configs = new HashSet<Bitmap.Config>();
configs.addAll(Arrays.asList(Bitmap.Config.values()));
if (Build.VERSION.SDK_INT >= 19) {
configs.add(null);
}
return Collections.unmodifiableSet(configs);
}
private interface BitmapTracker {
void add(Bitmap bitmap);
void remove(Bitmap bitmap);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册