我有很多图片说500片散布在20个左右的碎片上,图像都非常小而且都很好,但是我给了用户3种不同图像的选择,现在如果用户更改图像我得到一个OOM错误,所以我认为它处理图像的方式我认为我需要首先回收旧的,但我不知道如何做到这一点可以有人帮忙吗?
这里是我如何填充我的适配器我刚刚添加了两个项目来简化事情
private void prepareCardData(){
CardWriter cardWriter = new CardWriter(getResources().getDrawable(R.drawable.dog),"DOG","dog ");
cardMakerList.add(cardWriter);
cardWriter = new CardWriter(getResources().getDrawable(R.drawable.cat_ic),"CAT","cat ");
cardMakerList.add(cardWriter);
cardAdapter.notifyDataSetChanged();
}
这就是我真正等待共享偏好更改并调用方法
的地方private SharedPreferences.OnSharedPreferenceChangeListener listener = new
SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals("ICONS SELECTED")){
cardsChoice.setIcons(getActivity());
cardsToSet();
System.out.println("OneFrag pref listener");
}
}
};
public void cardsToSet(){
if (cardsChoice.bool_fragTwo == false) {
if (cardsChoice.group == 1) {
cardMakerList.clear();
prepareCardData();
cardsChoice.bool_fragTwo = true;
}
if (cardsChoice.group == 2) {
cardMakerList.clear();
prepareSimpleCardData();
cardsChoice.bool_fragTwo = true;
}
if (cardsChoice.group == 3) {
cardMakerList.clear();
preparePhotoCardData();
cardsChoice.bool_fragTwo = true;
}
}
}
所以如上所述,我认为我需要在自己的线程中运行它并清理和不再需要的图像,但我认为还有更多它可以帮助吗?
这是堆栈跟踪
06-12 17:39:47.878 13189-13219/ss.sealstudios.com.socialstories E/Surface: getSlotFromBufferLocked: unknown buffer: 0x8a12fe70
06-12 17:39:47.985 13189-13189/ss.sealstudios.com.socialstories I/System.out: OneFrag pref listener
06-12 17:39:47.987 13189-13189/ss.sealstudios.com.socialstories I/System.out: OneFrag pref listener
06-12 17:39:48.233 13189-13199/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 265MB to 256MB
06-12 17:39:48.380 13189-13189/ss.sealstudios.com.socialstories I/System.out: OneFrag pref listener
06-12 17:39:48.410 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.410 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.416 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc sticky concurrent mark sweep GC freed 108(4KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 254MB/256MB, paused 303us total 5.710ms
06-12 17:39:48.417 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.433 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 283MB to 256MB
06-12 17:39:48.433 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc partial concurrent mark sweep GC freed 5841(393KB) AllocSpace objects, 2(3MB) LOS objects, 1% free, 251MB/256MB, paused 793us total 15.361ms
06-12 17:39:48.493 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.494 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.502 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc sticky concurrent mark sweep GC freed 17(688B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 545us total 7.748ms
06-12 17:39:48.503 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.526 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.526 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc partial concurrent mark sweep GC freed 23(944B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 494us total 22.482ms
06-12 17:39:48.527 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.567 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.567 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc concurrent mark sweep GC freed 9(12KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 499us total 38.887ms
06-12 17:39:48.568 13189-13189/ss.sealstudios.com.socialstories I/art: Forcing collection of SoftReferences for 2025KB allocation
06-12 17:39:48.568 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.597 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.597 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc concurrent mark sweep GC freed 11(344B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 501us total 28.481ms
06-12 17:39:48.601 13189-13189/ss.sealstudios.com.socialstories W/art: Throwing OutOfMemoryError "Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM"
06-12 17:39:48.603 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.603 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.610 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc sticky concurrent mark sweep GC freed 3(448B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 484us total 6.214ms
06-12 17:39:48.611 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.643 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.643 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc partial concurrent mark sweep GC freed 6(192B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 1.131ms total 31.104ms
06-12 17:39:48.644 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.673 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.673 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 631us total 29.306ms
06-12 17:39:48.674 13189-13189/ss.sealstudios.com.socialstories I/art: Forcing collection of SoftReferences for 2025KB allocation
06-12 17:39:48.674 13189-13189/ss.sealstudios.com.socialstories I/art: Starting a blocking GC Alloc
06-12 17:39:48.704 13189-13189/ss.sealstudios.com.socialstories I/art: Clamp target GC heap from 287MB to 256MB
06-12 17:39:48.704 13189-13189/ss.sealstudios.com.socialstories I/art: Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 255MB/256MB, paused 306us total 29.616ms
06-12 17:39:48.705 13189-13189/ss.sealstudios.com.socialstories W/art: Throwing OutOfMemoryError "Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM"
06-12 17:39:48.709 13189-13189/ss.sealstudios.com.socialstories D/skia: --- allocation failed for scaled bitmap
06-12 17:39:48.709 13189-13189/ss.sealstudios.com.socialstories D/AndroidRuntime: Shutting down VM
06-12 17:39:48.724 13189-13189/ss.sealstudios.com.socialstories E/AndroidRuntime: FATAL EXCEPTION: main
Process: ss.sealstudios.com.socialstories, PID: 13189
java.lang.OutOfMemoryError: Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2738)
at android.content.res.Resources.loadDrawable(Resources.java:2643)
at android.content.res.Resources.getDrawable(Resources.java:833)
at android.content.res.Resources.getDrawable(Resources.java:786)
at ss.sealstudios.com.socialstories.TwoFragment.prepareCardData(TwoFragment.java:280)
at ss.sealstudios.com.socialstories.TwoFragment.cardsToSet(TwoFragment.java:245)
at ss.sealstudios.com.socialstories.TwoFragment$2.onSharedPreferenceChanged(TwoFragment.java:236)
at android.app.SharedPreferencesImpl$EditorImpl.notifyListeners(SharedPreferencesImpl.java:479)
at android.app.SharedPreferencesImpl$EditorImpl.apply(SharedPreferencesImpl.java:387)
at android.preference.Preference.tryCommit(Preference.java:1419)
at android.preference.Preference.persistString(Preference.java:1452)
at android.preference.ListPreference.setValue(ListPreference.java:148)
at android.preference.ListPreference.onDialogClosed(ListPreference.java:283)
at android.preference.DialogPreference.onDismiss(DialogPreference.java:395)
at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1328)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5527)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
答案 0 :(得分:4)
如果图像视图包含位图可绘制的实例
Drawable drawable = imageView.getDrawable();
if(drawable!=null && BitmapDrawable.class.isAssignableFrom(drawable.getClass())) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
if(bitmap != null && !bitmap.isRecycled()) bitmap.recycle();
}
但......
如果要从不大的可绘制文件夹(大到兆字节)中加载位图,那么您不应该遇到问题。
如果您加载资产,则需要检查它们是否适合您显示它们的位置,例如,如果您显示图像的区域是一个大小,则将ImageView设置为1024 x 1024大小的图像没有意义64x64。
OOM通常是由加载未知大小的图像引起的,或者只是如上所述简单地使图像尺寸错误,频繁更换ImageView通常不会给您带来最佳尺寸图像的问题。
您应该阅读有关位图的一些指导:
https://developer.android.com/training/displaying-bitmaps/index.html
适用于您的情况:
这是堆栈跟踪的基本片段:
FATAL EXCEPTION: main Process: ss.sealstudios.com.socialstories, PID: 13189
java.lang.OutOfMemoryError: Failed to allocate a 2073612 byte allocation with 559872 free bytes and 546KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2738)
at android.content.res.Resources.loadDrawable(Resources.java:2643)
at android.content.res.Resources.getDrawable(Resources.java:833) at android.content.res.Resources.getDrawable(Resources.java:786)
at ss.sealstudios.com.socialstories.TwoFragment.prepareCardData(TwoFragment.java:280)
无法分配带有559872个空闲字节的2073612字节分配和546KB直到OOM
一般:
没有更多代码我无法确定是否某个循环导致OOM或您没有释放资源...
在设置资源到图像视图之前,您也可以执行此操作(缩放图像):
Out of Memory Error ImageView issue
<强>小心!!! 强>
请勿使用已经回收的图片。
android&gt; 2.3.3并非严格要求您将获得异常:Canvas:尝试使用循环位图
bitmap.recycle()。如果您仍想强行收回此内存,则必须找到一种方法来检查何时确实不再需要位图(即,Canvas有机会完成其绘制操作)。
问题是您可能大量使用Bitmaps(分配速度可能比位图获得回收的速度更快)然后您可能希望尽快回收未使用的位图。当您完成使用时,您应该调用recycle()位图。
请务必记住在屏幕上显示位图时不要尝试回收位图。
所以:
^向VM表明运行垃圾收集器是个好时机。请注意,这只是一个提示。无法保证垃圾收集器实际运行。
调用 ImageView.setImageBitmap(); 或相似性不会回收位图使用的内存...
为什么呢?因为当你看看ImageView方法的impl时尤为:
private void updateDrawable(Drawable d) {
if (d != mRecycleableBitmapDrawable && mRecycleableBitmapDrawable != null) {
mRecycleableBitmapDrawable.setBitmap(null);
}
...
public void setImageResource(@DrawableRes int resId) {
// The resource configuration may have changed, so we should always
// try to load the resource even if the resId hasn't changed.
final int oldWidth = mDrawableWidth;
final int oldHeight = mDrawableHeight;
updateDrawable(null);
....
public void setImageBitmap(Bitmap bm) {
// Hacky fix to force setImageDrawable to do a full setImageDrawable
// instead of doing an object reference comparison
mDrawable = null;
if (mRecycleableBitmapDrawable == null) {
mRecycleableBitmapDrawable = new ImageViewBitmapDrawable(
mContext.getResources(), bm);
} else {
mRecycleableBitmapDrawable.setBitmap(bm);
}
setImageDrawable(mRecycleableBitmapDrawable);
}
另见:
https://developer.android.com/training/displaying-bitmaps/manage-memory.html