在我正在开发的应用程序中,用户输入的一部分是一系列图像。其中一些原始形式可能有 4MB 大。我调整它们的大小并旋转它们,然后将它们保存在设备内存的应用程序部分中以供以后使用。我遇到的问题是,即使我在保存后回收每个位图,我似乎也内存不足。
下面是主要处理
private class SaveImagesTask extends AsyncTask<Long, Void, Void>{
@Override
protected Void doInBackground(Long... ids){
long id = ids[0];
Iterator<ImageButton> itImg = arrBtnImage.iterator();
Iterator<TextView> itLbl = arrLblImage.iterator();
while(itImg.hasNext() && itLbl.hasNext()){
String imgPath = (String) itImg.next().getTag();
String imgLbl = itLbl.next().getText().toString().trim();
String imgName = imgLbl.replace(" ", "_").replace(",", "_");
imgName += ".jpg";
if(imgPath != null){
/* Save resized version of image */
File dir = getApplicationContext().getFilesDir();
dir = new File(dir, "temp/" + Long.toString(plantId));
boolean madeDir = dir.mkdirs();
File path = new File(dir, imgName);
Bitmap toSave = getScaledBitmap(imgPath, IMAGE_MAX_SIDE_LENGTH, IMAGE_MAX_SIDE_LENGTH);
try{
BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(path));
boolean insertSuccess = toSave.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
outStream.close();
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
toSave.recycle();
}//if
}//while(more images to process)
}// method: doInBackground(params)
}// inner class: saveImages extends AsyncTask
这是我调整图像大小的地方
private Bitmap getScaledBitmap(String picturePath, int newWidth, int newHeight){
/* Size */
BitmapFactory.Options sizeOptions = new BitmapFactory.Options();
sizeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, sizeOptions);
int sampleSize = 1;
int rawHeight = sizeOptions.outHeight;
int rawWidth = sizeOptions.outWidth;
if(rawHeight > newHeight || rawWidth > newWidth){
/* Find the dimension that needs to change the most */
int heightRatio = Math.round((float) rawHeight / (float) newHeight);
int widthRatio = Math.round((float) rawWidth / (float) newWidth);
sampleSize = (heightRatio > widthRatio ? heightRatio : widthRatio);
}//if(raw image is wider or taller than it should be){reduce size so neither is too large}
sizeOptions.inJustDecodeBounds = false;//Load pixels for display.
sizeOptions.inSampleSize = sampleSize;//Set shrink factor.
Bitmap scaledBitmap = BitmapFactory.decodeFile(picturePath, sizeOptions);
/* Rotation */
int rotation = 1;
try{
ExifInterface exif = new ExifInterface(picturePath);
rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
catch(IOException e){
e.printStackTrace();
}
int rotationInDegrees = 0;
if(rotation == ExifInterface.ORIENTATION_ROTATE_90)
rotationInDegrees = 90;
else if(rotation == ExifInterface.ORIENTATION_ROTATE_180)
rotationInDegrees = 180;
else if(rotation == ExifInterface.ORIENTATION_ROTATE_270)
rotationInDegrees = 270;
Matrix matrix = new Matrix();
if(rotation != 0f)
matrix.preRotate(rotationInDegrees);
return Bitmap.createBitmap(scaledBitmap, 0, 0,
scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
}// method: getScaledBitmap(String, int, int)
在我开始收到关于这个问题如此普遍的评论之前,我会指出我没有显示这些图像,所以我并不是想把所有这些都保存在内存中。我需要保留大图像,因为用户希望能够放大图片,但我正在调整它们的大小,因为它们不需要太大。我在 SO 上看到的关于图像和 OOM 错误的几乎所有其他解决方案都不适用于我对多个图像的背靠背访问。
所以就像我说的,我在保存后回收每个位图,但它们似乎仍在使用内存。知道我错过了什么吗?