죄송합니다. 반복되는 질문 인 것 같습니다.하지만 이미 게시 된 권장 사항 중 하나에 적합하지는 않습니다.OutOfMemoryError : 비트 맵 크기가 VM 예산을 초과합니다
내 응용 프로그램에 최대 20 개의 이미지 갤러리가 있습니다. 잠시 놀고 난 후에 앞뒤로 나는 OutOfMemoryError를 얻고있다.
이상한 점은 정적 참조를 갖고 있지 않으며 가능한 메모리 누수를 찾았으므로 지금까지 찾지 못했음을 확신 할 수 있습니다.
어쨌든 20 개의 이미지 (평균 100KB의 PNG)는 그리 좋아 보이지 않습니다. 그리고 뷰 캐시, 비트 맵용 SoftReference 홀더 등을 구현했습니다.
평균 20KB의 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 인 방법 :
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);
: 나는 이런 식으로 뭔가를했습니다
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에서
이
은 ImageCache입니다
내 갤러리에 코드를 표시하면 어떻게 이미지를 처리하나요? 내 갤러리에 60 개가 넘는 이미지 (100kb 이상)가있는 경우, 뭔가 잘못해야합니다 :) – WarrenFaith
당신은 어떤 의미가 있습니까? 코드를 보내 주시겠습니까? 전체 활동은 여기에 넣으려면 꽤 큰입니다 – lblasa
나는 단순히 내가 뭘 어떻게 할 ImageView에 비트 맵을 설정하는 어댑터에 질문을 업데이 트했습니다 – lblasa