Android BitmapDrawable 导致内存不足
Android BitmapDrawable results in out of memory
基本上我在 UI 中有 4 个 ImageView
,我想为它们设置图像。以下是相关代码:
private void showPhoto() {
// (re)set the image button's image based on our photo
Photo p = mCrime.getPhoto();
BitmapDrawable b = null;
if (p != null) {
String path = getActivity()
.getFileStreamPath(p.getFilename()).getAbsolutePath();
Log.i(TAG,"shown picture name is: "+p.getFilename());
// b = PictureUtils.getScaledDrawable(getActivity(), path);
// Log.i(TAG,"entered!");
if (cachedImageNames.size()==0)
cachedImageNames.add(0,path);
else{
boolean isExisted = false;
for (String imagePath: cachedImageNames){
if (imagePath.equals(path)){
isExisted = true;
break;
//cachedImageNames.add(0,path);
}
}
if (!isExisted)
cachedImageNames.add(0,path);
}
}
mCrimes = CrimeLab.get(getActivity()).getCrimes();
// mPhotoView.setImageDrawable(b);
Log.i(TAG,"image names' list size is: "+cachedImageNames.size());
if(!(cachedImageNames.size()<imageViews.size())){
for (int i=0; i<imageViews.size(); i++){
b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
imageViews.get(i).setImageDrawable(b);
}
}
else{
for (int i=0; i<cachedImageNames.size(); i++){
b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
imageViews.get(i).setImageDrawable(b);
}
}
}
在控制台中,显示这一行:
b= PictureUtils.getScaledDrawable(getActivity(),cachedImageNames.get(i));
导致这样的错误:
java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 16777216 free bytes and 36MB until OOM
我对 android
很陌生...有什么建议吗?
您正在尝试在堆上分配 50MB 的内存,这对于 android 驱动的设备来说太多了。如果确实有必要,您可以添加:
android:largeHeap="true"
在清单的 <application>
部分。但这通常是 不推荐的解决方案 。大多数应用程序不需要这个,而是应该专注于减少整体内存使用量以提高性能。启用此功能也不能保证可用内存的固定增加,因为某些设备受其总可用内存的限制。
正确解:
您需要查看打开了多少张图片以及它们有多大。请注意,一个非常普遍的误解是人们通常认为 文件大小 是内存中正在使用的内容。这是一个非常错误的假设。 PNG、JPG 等都是压缩格式。当您在设备上加载图像时,每个像素为 4 个字节。如果您有一个 2000x2000 像素的图像,加载时它会消耗 16MB 的 RAM - 这通常是典型(非游戏)应用程序的上限。
- 如果您不需要加载全尺寸图片,您可能需要查看 options.inJustDecodeBounds technique。
- 如果您没有使用显示屏幕中的所有图像,您想要使用 caching techniques。
基本上我在 UI 中有 4 个 ImageView
,我想为它们设置图像。以下是相关代码:
private void showPhoto() {
// (re)set the image button's image based on our photo
Photo p = mCrime.getPhoto();
BitmapDrawable b = null;
if (p != null) {
String path = getActivity()
.getFileStreamPath(p.getFilename()).getAbsolutePath();
Log.i(TAG,"shown picture name is: "+p.getFilename());
// b = PictureUtils.getScaledDrawable(getActivity(), path);
// Log.i(TAG,"entered!");
if (cachedImageNames.size()==0)
cachedImageNames.add(0,path);
else{
boolean isExisted = false;
for (String imagePath: cachedImageNames){
if (imagePath.equals(path)){
isExisted = true;
break;
//cachedImageNames.add(0,path);
}
}
if (!isExisted)
cachedImageNames.add(0,path);
}
}
mCrimes = CrimeLab.get(getActivity()).getCrimes();
// mPhotoView.setImageDrawable(b);
Log.i(TAG,"image names' list size is: "+cachedImageNames.size());
if(!(cachedImageNames.size()<imageViews.size())){
for (int i=0; i<imageViews.size(); i++){
b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
imageViews.get(i).setImageDrawable(b);
}
}
else{
for (int i=0; i<cachedImageNames.size(); i++){
b= PictureUtils.getScaledDrawable(getActivity(), cachedImageNames.get(i));
imageViews.get(i).setImageDrawable(b);
}
}
}
在控制台中,显示这一行:
b= PictureUtils.getScaledDrawable(getActivity(),cachedImageNames.get(i));
导致这样的错误:
java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 16777216 free bytes and 36MB until OOM
我对 android
很陌生...有什么建议吗?
您正在尝试在堆上分配 50MB 的内存,这对于 android 驱动的设备来说太多了。如果确实有必要,您可以添加:
android:largeHeap="true"
在清单的 <application>
部分。但这通常是 不推荐的解决方案 。大多数应用程序不需要这个,而是应该专注于减少整体内存使用量以提高性能。启用此功能也不能保证可用内存的固定增加,因为某些设备受其总可用内存的限制。
正确解:
您需要查看打开了多少张图片以及它们有多大。请注意,一个非常普遍的误解是人们通常认为 文件大小 是内存中正在使用的内容。这是一个非常错误的假设。 PNG、JPG 等都是压缩格式。当您在设备上加载图像时,每个像素为 4 个字节。如果您有一个 2000x2000 像素的图像,加载时它会消耗 16MB 的 RAM - 这通常是典型(非游戏)应用程序的上限。
- 如果您不需要加载全尺寸图片,您可能需要查看 options.inJustDecodeBounds technique。
- 如果您没有使用显示屏幕中的所有图像,您想要使用 caching techniques。