對不起,它似乎是一個重複的問題,但我認爲我不符合任何已發佈的建議。OutOfMemoryError:位圖大小超過VM預算
我的應用程序中有最多20張圖像的圖庫。玩了一段時間後,我得到OutOfMemoryError。
奇怪的是,我不抱任何靜態引用,我已經搜索了可能的內存泄漏問題,我可以保證,我還沒有發現一個至今。
無論如何,20幅圖像(100KB平均的PNG)並不像那麼多。我已經實現了一個視圖緩存,SoftReference的持有者爲位圖等
它是100KB的平均20個PNG圖像足以殺死我的應用程序?當真?我怎麼能擺脫這個?我跟着這個偉大的職位也
http://blog.jteam.nl/2009/09/17/exploring-the-world-of-android-part-2/
任何更多的想法?
這是ImageCache:
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);
向我們展示您的畫廊的代碼,你如何處理圖像那裏...因爲我在我的畫廊(比100KB大)超過60張圖片,你必須做一些錯誤:) – WarrenFaith 2011-04-14 15:30:41
你有什麼平均值向你發送代碼?整個活動是相當大的放在這裏 – lblasa 2011-04-14 15:36:27
我已經更新了問題,在適配器中,我只是將位圖設置爲ImageView – lblasa 2011-04-14 15:42:04