gpt4 book ai didi

android - 内存不足错误 : bitmap size exceeds VM budget

转载 作者:行者123 更新时间:2023-11-29 00:47:22 28 4
gpt4 key购买 nike

抱歉,这似乎是一个重复的问题,但我认为我不符合已发布的任何建议的条件。

我的应用程序中有一个最多包含 20 张图片的图库。来回玩了一段时间后,我遇到了 OutOfMemoryError。

奇怪的是我没有持有任何静态引用,而且我已经搜索了可能的内存泄漏,我可以保证到目前为止我还没有找到。

无论如何,20 张图像(平均 100KB 的 PNG)并没有那么多。我已经实现了 View 缓存、位图的 SoftReference 持有者等。

平均 100KB 的 20 张 PNG 图像足以杀死我的应用程序吗?严重地?我怎样才能摆脱这个?我也关注了这篇很棒的帖子

http://blog.jteam.nl/2009/09/17/exploring-the-world-of-android-part-2/

还有什么想法吗?

这是图像缓存:

public class AsyncImageLoader {

private final String TAG = getClass().getSimpleName();
private Context mContext;
private HashMap<String, SoftReference<Bitmap>> mImageCache;

public AsyncImageLoader(Context context) {
mContext = context;
mImageCache = new HashMap<String, SoftReference<Bitmap>>();
}

public Bitmap loadImage(final String identifier, final String imagePath, final ImageCallback imageCallback) {

if (mImageCache.containsKey(imagePath)) {
SoftReference<Bitmap> softReference = mImageCache.get(imagePath);
Bitmap bitmap = softReference.get();
if (bitmap != null) {
Log.i(TAG, "Retrieving image from cache: " + imagePath);
return bitmap;
}
}

final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
imageCallback.imageLoaded((Bitmap) message.obj, imagePath, identifier);
}
};

new Thread() {

@Override
public void run() {
Bitmap bitmap = loadImageFromPath(imagePath);
mImageCache.put(imagePath, new SoftReference<Bitmap>(bitmap));
Message message = handler.obtainMessage(0, bitmap);
handler.sendMessage(message);
}

}.start();

return null;
}

public Bitmap loadImageFromPath(String path) {

if(!GeneralUtilities.isEmpty(path)) {
Log.i(TAG, "Loading image: " + path);
InputStream imageInputStream = null;

try {
final AssetManager assetManager = mContext.getResources().getAssets();
imageInputStream = assetManager.open(path);

Bitmap bitmap = GeneralUtilities.decodeFile(imageInputStream);

imageInputStream.close();

return bitmap;
} catch (final IOException e) {
Log.e(TAG, e.getMessage());
}
}

return null;
}

public interface ImageCallback {
public void imageLoaded(Bitmap imageBitmap, String imagePath, String identifier);
}
}

GeneralUtilities.decodeFile 方法是:

public static Bitmap decodeFile(InputStream is){
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, o);

//The new size we want to scale to
final int REQUIRED_SIZE=140;

//Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;

while(true) {
if(width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
break;
width_tmp /= 2;
height_tmp /= 2;

scale *= 2;
}

//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(is, null, o2);
}

在 ArrayAdapter 的 getView 中,我有这样的东西:

final ImageView itemImage = cache.getHistoryImage();        
//final ImageView itemFrame = cache.getFrame();

String filename = item.getFilename().trim();

itemImage.setTag("front_" + filename);

Bitmap cachedImage = mAsyncImageLoader.loadImage("front_" + filename, filename, new ImageCallback() {

public void imageLoaded(Bitmap imageBitmap, String imagePath, String identifier) {

ImageView imageViewByTag = (ImageView) mGallery.findViewWithTag(identifier);
if (imageViewByTag != null) {
imageViewByTag.setImageBitmap(imageBitmap);
}
}
});

itemImage.setImageBitmap(cachedImage);

最佳答案

Android 框架中似乎存在错误,尽管 Google 似乎否认了这一点。

您是否通读了第 8488 期?

http://code.google.com/p/android/issues/detail?id=8488

我不确定这是否适用于您的代码 - 但您可以在设置/更新 ImageView 上的图像之前尝试这些建议。

基本上,它归结为调用 Bitmap.recycle()、清零引用(可能与您的情况无关)并显式调用 System.gc()。

垃圾收集器似乎是异步运行的,即使可以释放内存,新的垃圾收集器也可能会失败。

关于android - 内存不足错误 : bitmap size exceeds VM budget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5665260/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com