我在尝试显示背景图片时每次使用Galaxy S5时都会遇到崩溃。
此背景位于xxhdpi资源文件夹中,大小与S5屏幕(1080x1920)相同,因此我不需要调用" createScaledBitmap"用于缩放它。该图像的分辨率为JPG 96dpi。
当调用decodeResource时......崩溃!这怎么可能?我唯一能够加载这个"超级强大的#34;设备。
感谢!!!
在我的代码下面(S5的比例= 1):
public static Bitmap decodeBitmapFromResource(Resources res, int resId, float scale) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inSampleSize = calculateInSampleSize(options,
(int)(options.outWidth*scale),
(int)(options.outHeight*scale));
options.inJustDecodeBounds = false;
if (scale > 1) {
Bitmap bitmap = BitmapFactory.decodeResource(res, resId);
return Bitmap.createScaledBitmap(bitmap, (int)(options.outWidth*scale),
(int)(options.outHeight*scale), true);
}
return BitmapFactory.decodeResource(res, resId, options);
}
答案 0 :(得分:1)
试试这个
public static Bitmap decodeBitmapFromResource(String pathName, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
// return BitmapFactory.decodeResource(res, resId, options);
return BitmapFactory.decodeFile(pathName, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate ratios of height and width to requested height and
// width
final int heightRatio = Math.round((float) height / (float) reqHeight);
final int widthRatio = Math.round((float) width / (float) reqWidth);
// Choose the smallest ratio as inSampleSize value, this will
// guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
答案 1 :(得分:1)
我也经常多次面对这个问题......
尝试使用此代码..
private Bitmap decodeFile(File f) throws IOException {
Bitmap b = null;
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
o.inDither = false; // Disable Dithering mode
o.inPurgeable = true; // Tell to gc that whether it needs free memory,
// the Bitmap can be cleared
o.inInputShareable = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > metrics.heightPixels
|| o.outWidth > metrics.widthPixels) {
scale = (int) Math.pow(
2,
(int) Math.ceil(Math.log(metrics.heightPixels
/ (double) Math.max(o.outHeight, o.outWidth))
/ Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
return b;
}
并处理一些事情,例如在使用等之后将每个位图设为null。
答案 2 :(得分:0)
在应用程序标记的Manifest文件中添加此行。它并没有解决问题只是让你的应用程序有更多的内存:
android:largeHeap="true"
<强>更新强>
然而,使用largeHeap
并不是一个好的解决方案。这是谷歌关于此的文档。
但是,请求大堆的功能仅适用于a 一小组应用程序,可以证明需要消耗更多的RAM(例如 作为一个大型照片编辑应用程序)。 永远不要求大堆 因为你的内存不足而需要快速修复 - 你应该这样做 只有当你确切知道所有记忆的存在时才使用它 分配以及必须保留的原因。然而,即使你有信心 你的应用程序可以证明大堆的合理性,你应该避免请求它 尽可能的。使用额外的内存将越来越多 因为垃圾而损害整体用户体验 收集将花费更长时间,系统性能可能会更慢 任务切换或执行其他常见操作。
关于加载位图:
加载位图时,只能以您需要的分辨率将其保存在RAM中 对于当前设备的屏幕,如果原始屏幕缩小它 位图是一个更高的分辨率。请记住,位图的增加 分辨率导致所需的内存相应(增加2), 因为X和Y尺寸都增加了。
看一下这个页面并不错,它解释了管理内存的方法:
How Your App Should Manage Memory
所以我认为我的最后一个答案不是一个好的解决方案,您可能会重新考虑加载图像的策略。希望这个答案可以帮助你;)