final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.getByteCount() / 1024;
}
};
URL url = new URL("http://s2.goodfon.ru/image/260463-1920x1200.jpg");
Bitmap bitmap = BitmapFactory.decodeStream((InputStream) url.getContent(), null, options);
if(bitmap != null)
Log.i("Success", "BITMAP IS NOT NULL");
String key = "myKey";
Log.i("Get is null", "putting myKey");
mMemoryCache.put(key, bitmap);
Bitmap newBitmap = mMemoryCache.get(key);
if(newBitmap == null)
Log.i("newBitmap", "is null");
你好,这是一个代码。我成功从URL获取位图(Log说Bitmap不是null,我可以很容易地显示它)。然后我试图将它放入LruCache并将其恢复,但它返回null。 (Log表示newBitmap为null)。我的错误在哪里?请告诉我。 Android 4.1.2缓存大小8192 Kb。
答案 0 :(得分:8)
如果它在磁盘上是1.19 MB但在内存中是〜9 MB,这意味着作为压缩的JPEG文件,它是1.19 MB,一旦你将其提取到可以显示的Bitmap(未压缩)中,它将占用9 MB在记忆中。如果它是代码片段中url建议的1920 x 1200像素图像,则图像将占用1920 x 1200 x 4字节的内存(每个像素4个字节,表示ARGB值从0到256倍230万总像素= 9,216,000字节)。如果您使用1/8的可用内存用于此缓存,则可能/可能9MB超过总内存空间,因此Bitmap永远不会进入缓存或立即被驱逐。
你可能会想要在解码时对图像进行下采样,如果它那么大(使用BitmapFactory.Options.inSampleSize
...很多文档在网上使用,如果你还不熟悉的话。)< / p>
此外,您正在使用Runtime.maxMemory来计算缓存大小。这意味着您正在请求允许整个VM使用的最大内存量。
http://developer.android.com/reference/java/lang/Runtime.html#maxMemory%28%29
更常见的方法是使用ActivityManager.getMemoryClass()方法返回给您的值。
以下是文档中的示例代码段和方法定义,供参考。
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memClassBytes = am.getMemoryClass() * 1024 * 1024;
int cacheSize = memClassBytes / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize)
http://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass%28%29
答案 1 :(得分:0)
您还可以回收从lrucache
弹出的位图final Bitmap bmp = mLruCache.put(key, data);
if (bmp != null)
bmp.recycle();
答案 2 :(得分:0)
在以下行中将Runtime maxMemory除以1024时,Android示例出错了:
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
maxMemory的单位是Byte,它与'cacheSize'相同('/ 8'只表示它将使用当前Activity的八分之一可用内存)。因此,'/ 1024'会使'cacheSize'非常小,这样就不会在'mMemoryCache'中实际“缓存”位图。
解决方案将在上面的代码中删除'/ 1024'。