渲染ImageButtons时出现OutOfMemoryError

时间:2016-01-14 15:53:33

标签: java android

我出现内存不足错误,并不确定如何处理它。我将不胜感激任何帮助!我认为问题在于加载太多图像,但我怎么能避免这种情况呢?我想我只加载了15张卡+背景

01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime: FATAL EXCEPTION: main
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime: Process: caffeinereliantstudentstudios.pokerprobabilitycalculator, PID: 6063
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime: java.lang.OutOfMemoryError: Failed to allocate a 11287248 byte allocation with 4194304 free bytes and 5MB until OOM
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.loadDrawable(Resources.java:2540)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.TypedArray.getDrawable(TypedArray.java:870)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.drawable.StateListDrawable.inflateChildElements(StateListDrawable.java:170)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:115)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:1215)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.graphics.drawable.Drawable.createFromXml(Drawable.java:1124)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.loadDrawableForCookie(Resources.java:2630)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.loadDrawable(Resources.java:2540)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.getDrawable(Resources.java:806)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.content.res.Resources.getDrawable(Resources.java:771)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at caffeinereliantstudentstudios.pokerprobabilitycalculator.Main.setSuit(Main.java:193)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at caffeinereliantstudentstudios.pokerprobabilitycalculator.Main.onClick(Main.java:142)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.view.View.performClick(View.java:5198)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:21147)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:148)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5417)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
01-14 10:18:25.530 6063-6063/caffeinereliantstudentstudios.pokerprobabilitycalculator E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

代码:

package caffeinereliantstudentstudios.pokerprobabilitycalculator;

import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class Main extends FragmentActivity implements View.OnClickListener{
    //declaring variables
    private ImageView s1, s2;
    private Button back, next;
    private ImageButton[] ib = new ImageButton[13], suit = new ImageButton[4];
    private int[] own_c, own_c_id, own_suit, card_id;
    private int temp_suit, no_c = -1, spade = 0, heart = 1, club = 2, diamond = 3;
    private TextView intro;
    private boolean suit_select;
    private HorizontalScrollView hscroll;
    private LinearLayout cards;
    private Drawable d;
    private String path;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //set up scroller for cards
    hscroll = (HorizontalScrollView) findViewById(R.id.hscroll);
    hscroll.setVisibility(View.GONE);
    //assigning cards
    ib[0] = (ImageButton) findViewById(R.id.c1);
    ib[1] = (ImageButton) findViewById(R.id.c2);
    ib[2] = (ImageButton) findViewById(R.id.c3);
    ib[3] = (ImageButton) findViewById(R.id.c4);
    ib[4] = (ImageButton) findViewById(R.id.c5);
    ib[5] = (ImageButton) findViewById(R.id.c6);
    ib[6] = (ImageButton) findViewById(R.id.c7);
    ib[7] = (ImageButton) findViewById(R.id.c8);
    ib[8] = (ImageButton) findViewById(R.id.c9);
    ib[9] = (ImageButton) findViewById(R.id.c10);
    ib[10] = (ImageButton) findViewById(R.id.cj);
    ib[11] = (ImageButton) findViewById(R.id.cq);
    ib[12] = (ImageButton) findViewById(R.id.ck);

    //set up suits selection
    cards = (LinearLayout) findViewById(R.id.cards);
    suit[0] = (ImageButton) findViewById(R.id.spade);
    suit[1] = (ImageButton) findViewById(R.id.heart);
    suit[2] = (ImageButton) findViewById(R.id.club);
    suit[3] = (ImageButton) findViewById(R.id.diamond);

    //set up card listeners
    for(int i = 0; i < ib.length; i++){
        ib[i].setOnClickListener(this);
    }
    for(int i = 0; i < suit.length; i++){
        suit[i].setOnClickListener(this);
    }

    //set up back and next buttons
    back = (Button) findViewById(R.id.back_but);
    next = (Button) findViewById(R.id.next_but);
    //set on click listener
    back.setOnClickListener(this);
    next.setOnClickListener(this);
    //make it invisible to start with
    back.setVisibility(View.GONE);
    next.setVisibility(View.GONE);

    //we have no cards yet
    own_c = new int[2];
    own_c[0] = no_c;
    own_c[1] = no_c;
    own_c_id = new int[2];
    own_suit = new int[2];

    //selected cards on screen 1
    s1 = (ImageView) findViewById(R.id.s1);
    s2 = (ImageView) findViewById(R.id.s2);
    //set to invisible
    s1.setVisibility(View.GONE);
    s2.setVisibility(View.GONE);

    //directions
    intro = (TextView) findViewById(R.id.intro);

    //selecting suits first
    suit_select = true;

    //setting up card ids
    card_id = cardIdSetup();
}

@Override
public void onClick(View v){
    if(v.getId() == back.getId()){
        //reset card data
        own_c[0] = no_c;
        own_c[1] = no_c;
        own_suit[0] = no_c;
        own_suit[1] = no_c;
        //make the selected cards disappear
        s1.setVisibility(View.GONE);
        s2.setVisibility(View.GONE);
        //reveal proper selection menu
        hscroll.setVisibility(View.GONE);
        cards.setVisibility(View.VISIBLE);
        intro.setVisibility(View.VISIBLE);
        //remove buttons
        next.setVisibility(View.GONE);
        back.setVisibility(View.GONE);
    }else if(v.getId() == next.getId()){
        //moving to next activity
        Intent intent = new Intent(getBaseContext(), PublicCard.class);
        //pass data
        intent.putExtra("own_c", own_c);
        intent.putExtra("own_c_id", own_c_id);
        intent.putExtra("own_suit", own_suit);
        //start activity
        startActivity(intent);
        //remove transition
        overridePendingTransition(0,0);
    }else if(suit_select){//if they haven't selected a suit yet
        for(int i = 0; i < suit.length; i++){//check which suit they want
            if(v.getId() == suit[i].getId()){
                temp_suit = i;
                suit_select = false;//make the next selection be for cards
                hscroll.setVisibility(View.VISIBLE);//make card section screen visible
                //show only those that weren't already selected
                revealNotSelected(temp_suit, own_suit, own_c);
                //remove suit selection
                cards.setVisibility(View.GONE);
                //set drawable of cards for proper suit
                setSuit(temp_suit);
            }
        }
    }else{//time for selecting the card
        for(int i = 0; i < ib.length; i++){
            if(v.getId() == ib[i].getId()){
                d = ib[i].getBackground();//get background
                if(own_c[1] == -1){//set card to right
                    own_c[1] = i;
                    own_suit[1] = temp_suit;
                    own_c_id[1] = v.getId();
                    s2.setBackgroundDrawable(d);
                    s2.setVisibility(View.VISIBLE);
                    ib[i].setVisibility(View.GONE);
                }else if(own_c[0] == -1){//set card to left
                    own_c[0] = i;
                    own_suit[0] = temp_suit;
                    own_c_id[0] = v.getId();
                    s1.setBackgroundDrawable(d);
                    s1.setVisibility(View.VISIBLE);
                }
                //once we know which card they want, we can
                //go back to the suit selection screen.
                //loop will go through quickly
                hscroll.setVisibility(View.GONE);
                suit_select = true;
                cards.setVisibility(View.VISIBLE);
            }
        }
    }
    //ensure proper buttons are shown
    if(own_c[0] != no_c && own_c[1] != no_c){
        next.setVisibility(View.VISIBLE);
        intro.setVisibility(View.GONE);
    }else{
        next.setVisibility(View.GONE);
        intro.setVisibility(View.VISIBLE);
    }

    if(own_c[0] != own_c[1]){
        back.setVisibility(View.VISIBLE);
    }else{
        back.setVisibility(View.GONE);
    }
}

private void setSuit(int suit){
    int suit_num = suit * 13;
    int temp;
    for(int index = 0; index < this.ib.length; index++) {
        temp = suit_num + index;
            this.ib[index].setBackgroundDrawable(getResources().getDrawable(card_id[temp]));
    }
}

private int[] cardIdSetup(){
    int[] temp = new int[52];
    temp[0] = R.drawable.c0;
    temp[1] = R.drawable.c1;
    temp[2] = R.drawable.c2;
    temp[3] = R.drawable.c3;
    temp[4] = R.drawable.c4;
    temp[5] = R.drawable.c5;
    temp[6] = R.drawable.c6;
    temp[7] = R.drawable.c7;
    temp[8] = R.drawable.c8;
    temp[9] = R.drawable.c9;
    temp[10] = R.drawable.c10;
    temp[11] = R.drawable.c11;
    temp[12] = R.drawable.c12;
    temp[13] = R.drawable.c13;
    temp[14] = R.drawable.c14;
    temp[15] = R.drawable.c15;
    temp[16] = R.drawable.c16;
    temp[17] = R.drawable.c17;
    temp[18] = R.drawable.c18;
    temp[19] = R.drawable.c19;
    temp[20] = R.drawable.c20;
    temp[21] = R.drawable.c21;
    temp[22] = R.drawable.c22;
    temp[23] = R.drawable.c23;
    temp[24] = R.drawable.c24;
    temp[25] = R.drawable.c25;
    temp[26] = R.drawable.c26;
    temp[27] = R.drawable.c27;
    temp[28] = R.drawable.c28;
    temp[29] = R.drawable.c29;
    temp[30] = R.drawable.c30;
    temp[31] = R.drawable.c31;
    temp[32] = R.drawable.c32;
    temp[33] = R.drawable.c33;
    temp[34] = R.drawable.c34;
    temp[35] = R.drawable.c35;
    temp[36] = R.drawable.c36;
    temp[37] = R.drawable.c37;
    temp[38] = R.drawable.c38;
    temp[39] = R.drawable.c39;
    temp[40] = R.drawable.c40;
    temp[41] = R.drawable.c41;
    temp[42] = R.drawable.c42;
    temp[43] = R.drawable.c43;
    temp[44] = R.drawable.c44;
    temp[45] = R.drawable.c45;
    temp[46] = R.drawable.c46;
    temp[47] = R.drawable.c47;
    temp[48] = R.drawable.c48;
    temp[49] = R.drawable.c49;
    temp[50] = R.drawable.c50;
    temp[51] = R.drawable.c51;
    return temp;
}

private void revealNotSelected(int suit, int[] own_suits, int[] own_cards){
    for(int j = 0; j < this.ib.length; j++) {
        this.ib[j].setVisibility(View.VISIBLE);
        for (int k = 0; k < own_suits.length; k++) {
            if (suit == own_suits[k] && own_cards[k] == j) {
                this.ib[j].setVisibility(View.GONE);
            }
        }
    }
}
该应用程序是一个扑克概率计算器。主类包含用户在他手中选择卡片的代码,但首先选择适合卡片的卡片,然后选择卡片(以避免同时呈现52张卡片)。重复第二张卡,然后您可以选择继续进入第二个屏幕,在那里您可以选择发出的卡片 在我为第一张卡片选择了西装后,它崩溃的部分就在了。此时,只应渲染背景和4张卡片。按下套装后,4张牌消失,并且该套牌中的13张牌被渲染并显示出来。现在还会出现重置选择按钮(文本也会更改以引导用户选择卡) 谢谢!

1 个答案:

答案 0 :(得分:0)

您必须使用BitmapFactory.options以较低的分辨率加载图像,否则将导致错误

private void setSuit(int suit){
    int suit_num = suit * 13;
    int temp;
    for(int index = 0; index < this.ib.length; index++) {
        temp = suit_num + index;
        BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeResource (getResources(), card_id[temp],options)                                         
                options.inSampleSize = calculateInSampleSize(options,100,100);//100 and 100 whatever you want as scale
                    options.inJustDecodeBounds = false;
                Bitmap yourSelectedImage = BitmapFactory.decodeResource(getResources(),card_id[temp],options);
           BitmapDrawable ob = new BitmapDrawable(getResources(), yourSelectedImage)
            this.ib[index].setBackgroundDrawable(ob);
    }
}

帮助方法

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;
    }