在我的Android应用中,我有一个自定义的ImageView,它基于用户交互,需要更新其图像。 ImageView只能有两张图像,分别代表卡片的背面和正面。 因此,当用户点击按钮时,我需要显示卡的背面(将我的自定义ImageView图像设置到卡的背面,当用户再次按下按钮时,将前图像设置为ImageView可绘制)。
为了实现这一点,我在自定义ImageView中有两种方法:
public void showBack() {
setImageResource(R.drawable.card_back);
}
public void showFront() {
setImageResource(R.drawable.card_front);
}
当然,这很好用,但我的应用程序的内存消耗有时会接近114 MB,并且随着用户点击按钮(旋转卡)而增加。
由于这个原因,我认为问题可能是由于图像的变化而产生的。 图像很小,一个是104.6KB,另一个是80.4KB(PNG格式),所以我不明白为什么我的应用程序消耗了这么多内存(可能因为图像分配很多次并且从未回收过?,或者可能是因为Android的drawables缓存系统?)
那么,我该怎么做才能解决我的问题?
谢谢。
图片尺寸为335 x 501
答案 0 :(得分:1)
所以这里有一些因素可以发挥作用。 imageView维度(我假设)已在dp
中定义。根据屏幕分辨率,这会转换为从手机到手机的像素数。因此,相同的drawable,当连接到不同手机中的imageView时,必须缩放以匹配px
中显示它所需的imageView
。
此扩展需要大量内存,这会导致OOM异常。有些手机有一个大的RAM,可以完成这个缩放而不会造成任何问题,而较旧的型号可能无法实现。
当您加载imageView
时,原始图像将保留在内存中,然后重新调整。我建议获取imageView
的像素尺寸,然后相应地缩放图像,以产生最佳拟合。这将减少内存消耗。
This answer和this应该可以帮助您获取imageView的尺寸。
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_resource);
private Bitmap ScaleImage(Bitmap bitmap){
//the original dimension of the bitmap
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int requiredWidth=0;
int requiredHeight=0;
//todo: Calculate the required dimensions of the bitmap as per the imageView
ExifInterface exif;
Matrix matrix = new Matrix();
/* In case you need to rotate the bitmap
try {
exif = new ExifInterface(value);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
Log.d("EXIF", "Exif: " + orientation);
if (orientation == 6) {
matrix.postRotate(90);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 3) {
matrix.postRotate(180);
Log.d("EXIF", "Exif: " + orientation);
} else if (orientation == 8) {
matrix.postRotate(270);
Log.d("EXIF", "Exif: " + orientation);}
}catch (IOException e){e.printStackTrace();}
*/
matrix.postScale(requiredWidth/originalWidth, requiredHeight/originalHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,width, height, matrix, true);
return resizedBitmap;
}
最后
public void showFront() {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.icon_resource);
Bitmap scaledBitmap = ScaleImage(icon);
setImageResource(scaledBitmap);
}
理想情况下,您希望将图像的缩放比例移至Async Task
,以便不阻止主线程。
请告诉我这是否有效。
答案 1 :(得分:0)
图像的大小在这里不起作用。另一方面,尺寸确实如此。因此,如果您使用大尺寸的图像并在ImageView中使用较小的分辨率,那么这将是一个问题,您最终可能会遇到OOM(Out of Memory Exception)。
请参阅: http://developer.android.com/training/displaying-bitmaps/index.html
答案 2 :(得分:0)
根据我在加载图片时的个人经验,您应该始终使用毕加索库。它有助于解决所有内存问题,让您轻松扩展等。 this