Skip to content

Commit 3400d6e

Browse files
bvibberyuvipanda
authored andcommitted
bug 50733: Fix OOM error on low-memory devices
LRU bitmap cache ate too much memory on low-memory devices like the old Nexus One and some of our testers' devices. Use the in memory cache only for higher end devices Change-Id: Ibe238c82d5891a8a25bddcab1ae3d3738a044c41
1 parent c5042b0 commit 3400d6e

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

commons/src/main/java/org/wikimedia/commons/CommonsApplication.java

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import android.os.Build;
1616

1717
import android.support.v4.util.LruCache;
18+
import android.util.Log;
1819
import com.android.volley.RequestQueue;
1920
import com.nostra13.universalimageloader.cache.disc.impl.TotalSizeLimitedDiscCache;
2021
import com.nostra13.universalimageloader.cache.memory.impl.LimitedAgeMemoryCache;
@@ -112,29 +113,41 @@ public void onCreate() {
112113
// Initialize EventLogging
113114
EventLog.setApp(this);
114115

116+
117+
// based off https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
118+
// Cache for 1/8th of available VM memory
119+
long maxMem = Runtime.getRuntime().maxMemory();
120+
if (maxMem < 48L * 1024L * 1024L) {
121+
// Cache only one bitmap if VM memory is too small (such as Nexus One);
122+
Log.d("Commons", "Skipping bitmap cache; max mem is: " + maxMem);
123+
imageCache = new LruCache<String, Bitmap>(1);
124+
} else {
125+
int cacheSize = (int) (maxMem / (1024 * 8));
126+
Log.d("Commons", "Bitmap cache size " + cacheSize + " from max mem " + maxMem);
127+
imageCache = new LruCache<String, Bitmap>(cacheSize) {
128+
@Override
129+
protected int sizeOf(String key, Bitmap bitmap) {
130+
// bitmap.getByteCount() not available on older androids
131+
int bitmapSize;
132+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
133+
bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
134+
} else {
135+
bitmapSize = bitmap.getByteCount();
136+
}
137+
// The cache size will be measured in kilobytes rather than
138+
// number of items.
139+
return bitmapSize / 1024;
140+
}
141+
};
142+
}
143+
115144
DiskBasedCache cache = new DiskBasedCache(getCacheDir(), 16 * 1024 * 1024);
116145
volleyQueue = new RequestQueue(cache, new BasicNetwork(new HurlStack()));
117146
volleyQueue.start();
118147
}
119148

120149
private com.android.volley.toolbox.ImageLoader imageLoader;
121-
// based off https://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
122-
// Cache for 1/8th of available VM memory
123-
private LruCache<String, Bitmap> imageCache = new LruCache<String, Bitmap>((int) (Runtime.getRuntime().maxMemory() / (1024 * 8))) {
124-
@Override
125-
protected int sizeOf(String key, Bitmap bitmap) {
126-
// bitmap.getByteCount() not available on older androids
127-
int bitmapSize;
128-
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
129-
bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
130-
} else {
131-
bitmapSize = bitmap.getByteCount();
132-
}
133-
// The cache size will be measured in kilobytes rather than
134-
// number of items.
135-
return bitmapSize / 1024;
136-
}
137-
};
150+
private LruCache<String, Bitmap> imageCache;
138151

139152
public com.android.volley.toolbox.ImageLoader getImageLoader() {
140153
if(imageLoader == null) {

0 commit comments

Comments
 (0)