Android 16571536字节分配的内存不足
基本上,我正在为android 4.4.2锁屏背景添加一个墙纸选择器,当图像设置好后,我关闭屏幕,然后再打开以查看锁屏,我的屏幕变黑,logcat给我一个内存分配错误。到目前为止,我已经尝试使用位图解码文件(字符串路径名),我还重新设置了使用位图解码文件(字符串路径名,选项选项选项)的基础,但每次结果都是一样的 以下是用于设置图像的原始方法:Android 16571536字节分配的内存不足,android,image,bitmap,bitmapfactory,Android,Image,Bitmap,Bitmapfactory,基本上,我正在为android 4.4.2锁屏背景添加一个墙纸选择器,当图像设置好后,我关闭屏幕,然后再打开以查看锁屏,我的屏幕变黑,logcat给我一个内存分配错误。到目前为止,我已经尝试使用位图解码文件(字符串路径名),我还重新设置了使用位图解码文件(字符串路径名,选项选项选项)的基础,但每次结果都是一样的 以下是用于设置图像的原始方法: private static final String WALLPAPER_IMAGE_PATH = "/data/data/com.an
private static final String WALLPAPER_IMAGE_PATH =
"/data/data/com.android.settings/files/lockscreen_wallpaper.png";
private KeyguardUpdateMonitorCallback mBackgroundChanger = new KeyguardUpdateMonitorCallback() {
@Override
public void onSetBackground(Bitmap bmp) {
if (bmp != null) {
mKeyguardHost.setCustomBackground(
new BitmapDrawable(mContext.getResources(), bmp));
}
else {
File file = new File(WALLPAPER_IMAGE_PATH);
if (file.exists()) {
mKeyguardHost.setCustomBackground(
new BitmapDrawable(mContext.getResources(), WALLPAPER_IMAGE_PATH));
}
else {
mKeyguardHost.setCustomBackground(null);
}
}
updateShowWallpaper(bmp == null);
}
};
在以下情况下,从案例1调用:
public void setCustomBackground(Drawable d) {
if (!mAudioManager.isMusicActive()) {
int mBackgroundStyle = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.LOCKSCREEN_BACKGROUND_STYLE, 2);
int mBackgroundColor = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.LOCKSCREEN_BACKGROUND_COLOR, 0x00000000);
switch (mBackgroundStyle) {
case 0:
d = new ColorDrawable(mBackgroundColor);
d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER);
mCustomBackground = d;
break;
case 1:
KeyguardUpdateMonitor.getInstance(getContext()).dispatchSetBackground(null);
break;
case 2:
default:
mCustomBackground = d;
}
computeCustomBackgroundBounds(mCustomBackground);
setBackground(mBackgroundDrawable);
}
if (!ActivityManager.isHighEndGfx()) {
mCustomBackground = d;
if (d != null) {
d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER);
}
computeCustomBackgroundBounds(mCustomBackground);
invalidate();
} else {
if (getWidth() == 0 || getHeight() == 0) {
d = null;
}
if (d == null) {
mCustomBackground = null;
setBackground(mBackgroundDrawable);
return;
}
Drawable old = mCustomBackground;
if (old == null) {
old = new ColorDrawable(0);
computeCustomBackgroundBounds(old);
}
d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER);
mCustomBackground = d;
computeCustomBackgroundBounds(d);
Bitmap b = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
mBackgroundDrawable.draw(c);
Drawable dd = new BitmapDrawable(b);
mTransitionBackground = new TransitionDrawable(new Drawable[]{old, dd});
mTransitionBackground.setCrossFadeEnabled(true);
setBackground(mTransitionBackground);
mTransitionBackground.startTransition(200);
mCustomBackground = dd;
invalidate();
}
if (d != null) {
d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER);
}
computeCustomBackgroundBounds(mCustomBackground);
invalidate();
}
这是我的logcat输出:
I/dalvikvm-heap(13100): Forcing collection of SoftReferences for 16571536-byte allocation
E/dalvikvm-heap(13100): Out of memory on a 16571536-byte allocation.
I/dalvikvm(13100): "main" prio=5 tid=1 RUNNABLE
I/dalvikvm(13100): | group="main" sCount=0 dsCount=0 obj=0x4159fe40 self=0x414d4548
I/dalvikvm(13100): | sysTid=13100 nice=0 sched=0/0 cgrp=apps handle=1074098536
I/dalvikvm(13100): | state=R schedstat=( 0 0 0 ) utm=877 stm=93 core=1
I/dalvikvm(13100): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
I/dalvikvm(13100): at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:613)
I/dalvikvm(13100): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:589)
I/dalvikvm(13100): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:369)
I/dalvikvm(13100): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:395)
I/dalvikvm(13100): at com.android.keyguard.KeyguardViewManager$1.onSetBackground(KeyguardViewManager.java:127)
I/dalvikvm(13100): at com.android.keyguard.KeyguardUpdateMonitor.dispatchSetBackground(KeyguardUpdateMonitor.java:452)
I/dalvikvm(13100): at com.android.keyguard.KeyguardViewManager$ViewManagerHost.setCustomBackground(KeyguardViewManager.java:302)
您的内存不足,因为您没有仔细处理图像。查看以下问题/答案,以更好地了解尝试加载图像时会发生什么情况: 如果你是一个新的开发人员,那么我建议你只使用任何好的库来为你加载部分,否则加载图像会非常困难 Android通用图像加载器:广泛使用的库 备选毕加索库:一行代码即可完成此任务: 更新: 位图占用大量内存,特别是对于像这样的丰富图像 照片。例如,Galaxy Nexus上的相机会拍照 高达2592x1936像素(500万像素)。如果位图配置 使用的是ARGB_8888(Android 2.3以后的默认版本),然后 将此图像加载到内存大约需要19MB的内存(2592*1936*4 字节),立即耗尽某些设备上的每应用程序限制
也许可以尝试使用另一个更小的图像?问题是,这是一个用户从gallery中选择的图像,因此图像需要以某种方式进行压缩…如果无法加载正常图像,则设置自定义锁屏背景的选项相对无用。我不明白为什么要将图像压缩为PNG,它在减少图像的内存占用方面没有任何作用,如果图像是图片,生成的PNG文件将比原始JPG文件大得多。但主要问题是,您试图分配一个16MB的位图,这意味着一个4M像素的图像。因此,问题在于屏幕是否能够以其本机分辨率显示4M像素的图像。因为只有Nexus 10具有如此高的分辨率,我想说不。如果你不想使用第三方库,只需使用@Sharj提供的第一个链接,那里的解决方案会将图像重新缩放到所需的大小。我在设置中添加了设置图像的代码,以帮助澄清我如何处理图像(位图.CompressFormat格式、整数质量、输出流)用于压缩图像?问题不在于功能,而在于大小。您的设备内存不足。即使您优化了解决方案,也不能保证它能在所有设备上运行。最好使用由顶级开发人员开发和使用的库。这只是一行代码。我同意,但我怀疑团队的其他成员也会使用非谷歌代码来做这类事情,因为在4.4.2之前,同样的事情是没有问题的……但是上面的更新似乎给了我所需要的
} else if (requestCode == REQUEST_PICK_WALLPAPER) {
FileOutputStream wallpaperStream = null;
try {
wallpaperStream = getActivity().openFileOutput(WALLPAPER_NAME,
Context.MODE_WORLD_READABLE);
} catch (FileNotFoundException e) {
return; // NOOOOO
}
Uri selectedImageUri = getLockscreenExternalUri();
Bitmap bitmap;
if (data != null) {
Uri mUri = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(),
mUri);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, wallpaperStream);
Toast.makeText(getActivity(), getResources().getString(R.string.
background_result_successful), Toast.LENGTH_LONG).show();
Settings.System.putInt(getContentResolver(),
Settings.System.LOCKSCREEN_BACKGROUND_STYLE, 1);
updateVisiblePreferences();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
bitmap = BitmapFactory.decodeFile(selectedImageUri.getPath());
bitmap.compress(Bitmap.CompressFormat.PNG, 100, wallpaperStream);
} catch (NullPointerException npe) {
Log.e(TAG, "SeletedImageUri was null.");
Toast.makeText(getActivity(), getResources().getString(R.string.
background_result_not_successful), Toast.LENGTH_LONG).show();
super.onActivityResult(requestCode, resultCode, data);
return;
}
}
}