2010-08-27 108 views
2

我见过这个问题很多次被问过,但没有一个答案真的在我所做的事情中有意义... 我有一个安卓游戏(看源码google source control) 这是一款纸牌游戏,我使用了一种每轮都重新绘制每一只手的方法 - 这可能是浪费,但我想不出一个更好的方法来做到这一点。 下面是redrawHand方法的代码:如何解决“java.lang.OutOfMemoryError:位图大小超过虚拟机预算”的错误android

private void redrawHand(Hand hand) { 
    ImageView[] cardView = hand.getCardsViews(); 
    View container = hand.getContainer(); 
    for (int i = 0; i < GameData.YANIV_NUM_CARDS; i++) { 
    PlayingCard card = hand.getCardByLocation(i); 
    if (card != null) { 
    // Show Card 
    cardView[i].setVisibility(View.VISIBLE); 
    int resId; 
    if (hand.shouldCardsBeShown()) { 
    resId = card.getImageResourceId(); 
    } else { 
    resId = R.drawable.back; 
    } 
    cardView[i].setImageResource(resId); 
// TODO: Disgusting patch, need to fix asap!!! 
if (hand.isHumanPlayer()) { 
// Show isSelected 
// when selected, move up 15 pixels 
boolean isSelected = hand.isCardSelected(i); 
((LinearLayout.LayoutParams) cardView[i].getLayoutParams()).bottomMargin = isSelected? 15 : 0; 
} } else { 
cardView[i].setVisibility(View.INVISIBLE); } } // Set player name hand.getHandLabelView().setText(hand.getHandLabel()); container.requestLayout(); } 

安装ACRA(http://code.google.com/p/acra/wiki/ACRAHowTo)我已经开始渐渐从声称说设备以下的崩溃报告后:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:363) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:212) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:673) at android.content.res.Resources.loadDrawable(Resources.java:1639) at android.content.res.Resources.getDrawable(Resources.java:535) at android.widget.ImageView.resolveUri(ImageView.java:541) at android.widget.ImageView.setImageResource(ImageView.java:293) at com.geekadoo.ui.Yaniv.redrawHand(Yaniv.java:765) at com.geekadoo.ui.Yaniv.performYaniv(Yaniv.java:539) at com.geekadoo.ui.Yaniv.performYanivHandler(Yaniv.java:503) at com.geekadoo.ui.Yaniv.access$1(Yaniv.java:502) at com.geekadoo.ui.Yaniv$2.onClick(Yaniv.java:323) at android.view.View.performClick(View.java:2196) at android.view.View.onTouchEvent(View.java:3849) at android.widget.TextView.onTouchEvent(TextView.java:6376) at android.view.View.dispatchTouchEvent(View.java:3385) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:872) at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1764) at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1213) at android.app.Activity.dispatchTouchEvent(Activity.java:2066) at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1748) at android.view.ViewRoot.handleMessage(ViewRoot.java:1561) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:3977) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540) at dalvik.system.NativeStart.main(Native Method)

我无法理解为什么这发生了 - 有没有内存泄漏?我应该以某种方式发布我失踪的东西吗? 请帮忙,有很多人因此无法享受这个免费的开源游戏。 谢谢!

+0

当我在MapView上快速放大时,我总是这样做。我看到Romain Guy(Google工程师)的一个回答,那就是说你使用的内存太多,修复它只需要少用一点。你有太多的大Bitmaps分配,并因此抛出一个错误。不是很具体,但这可能是这种情况。如果你编辑你的文章并正确格式化,我会更多地阅读你的代码。 – 2010-08-28 00:03:06

+0

正如你可以看到我的代码在谷歌代码,我没有使用大的位图,我怀疑内存泄漏,但无法弄清楚为什么会发生... – ekatz 2010-08-30 16:16:23

回答

0

从堆栈跟踪中,您可以看到一个位图被分配为redrawHand中setImageResource()调用的副作用。

通常,像这样的位图和资源应该在启动时分配一次,而不是在每次重绘时分配一次。如果您在onCreate(或onResume?)中加载图像资源,然后在重绘期间引用这些资源,我认为您将避免该错误。

我不完全清楚为什么这表现为内存泄漏。从技术上讲,如果你分配新的位图内存来支持View,旧内存应该被释放。也许GC在某些系统上落后了,无法跟上你分配新位图的速度?

相关问题