【问题标题】:ArrayOutOfBoundException while creating button array创建按钮数组时出现 ArrayOutOfBoundException
【发布时间】:2014-01-19 02:45:53
【问题描述】:

我正在开发一个需要按钮的行和列的游戏。我真的无法弄清楚我的代码中是如何发生 ArrayIndexOutOfBound 异常的。帮我找出错误。谢谢

这是我的 XML 视图

 <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tl1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:stretchColumns="0,2"
    android:background="@drawable/game"
    android:alpha="20" >

    <TableRow
        android:id="@+id/tr1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/tvNoOfMines"
            android:layout_height="100dp"
            android:layout_column="0"
            android:gravity="center"
            android:text="000" >
        </TextView>

        <ImageButton
            android:id="@+id/ibSmiley"
            android:layout_height="wrap_content"
            android:layout_column="1"
            android:background="@drawable/custom_reaction" >
        </ImageButton>

        <TextView
            android:id="@+id/tvTimer"
            android:layout_height="100dp"
            android:layout_column="2"
            android:gravity="center"
            android:text="000" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tr2"
        android:layout_width="match_parent"
        android:layout_height="50dp" >
    </TableRow>

    <TableRow android:id="@+id/tr3" >

        <TableLayout
            android:id="@+id/tlMineFields"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_span="3"
            android:stretchColumns="*" 
            android:scrollbars="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:padding="5dp">
        </TableLayout>
    </TableRow>

</TableLayout>

这是我访问按钮数组的代码部分

 private void createMineFields() {
        // TODO Auto-generated method stub
        buttonBlock = new ButtonBlock[noOfMineFields][noOfMineFields];

        for(int i=0;i<noOfMineFields;i++){
            for(int j=0;j<noOfMineFields;j++){
                buttonBlock[i][j]=new ButtonBlock(this);
                buttonBlock[i][j].setOnClickListener(this);
                buttonBlock[i][j].setOnLongClickListener(this);
            }
        }
    }


private void placeMineFields() {
        // TODO Auto-generated method stub

        for (int i = 0; i < noOfMineFields; i++) {
            tablerow = new TableRow(this);
            tablerow.setLayoutParams(new LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));
            //tablerow.setPadding(blockPadding, blockPadding, blockPadding, blockPadding);
            for (int j = 0; j < noOfMineFields; j++) {
                buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));
                buttonBlock[i][j].setPadding(blockPadding, blockPadding, blockPadding, blockPadding);
                String createId = "" + (i + 1) + "" + j;
                buttonBlock[i][j].setId(Integer.parseInt(createId));
                tablerow.addView(buttonBlock[i][j]);

            }

            tablelayout.addView(tablerow,new TableLayout.LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));

        }
    }

我首先调用 createMineFields() 字段,然后调用 placeMineFields()。我是 android 和编程新手。帮我弄清楚 ArrayIndexOutOfBound 异常发生的位置和方式。

这是在 LogCat 中发出的错误

  01-18 23:12:54.805: D/dalvikvm(2766): GC_EXTERNAL_ALLOC freed 52K, 53% free 2562K/5379K, external 1625K/2137K, paused 59ms
01-18 23:13:52.445: D/dalvikvm(2766): GC_EXTERNAL_ALLOC freed 8K, 52% free 2583K/5379K, external 2525K/3154K, paused 33ms
01-18 23:13:52.615: D/AndroidRuntime(2766): Shutting down VM
01-18 23:13:52.615: W/dalvikvm(2766): threadid=1: thread exiting with uncaught exception (group=0x40015560)
01-18 23:13:52.625: E/AndroidRuntime(2766): FATAL EXCEPTION: main
01-18 23:13:52.625: E/AndroidRuntime(2766): java.lang.RuntimeException: Unable to start activity ComponentInfo{btdw.agilan.minesweeper/btdw.agilan.minesweeper.Game}: java.lang.ArrayIndexOutOfBoundsException
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.os.Looper.loop(Looper.java:123)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.main(ActivityThread.java:3683)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at java.lang.reflect.Method.invokeNative(Native Method)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at java.lang.reflect.Method.invoke(Method.java:507)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at dalvik.system.NativeStart.main(Native Method)
01-18 23:13:52.625: E/AndroidRuntime(2766): Caused by: java.lang.ArrayIndexOutOfBoundsException
01-18 23:13:52.625: E/AndroidRuntime(2766):     at btdw.agilan.minesweeper.Game.placeMineFields(Game.java:115)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at btdw.agilan.minesweeper.Game.onCreate(Game.java:58)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-18 23:13:52.625: E/AndroidRuntime(2766):     ... 11 more

这是我调用 createminefields() 和 placeminefields() 的代码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mine);
        initialize();
        placeMineFields();
    }



   private void initialize() {
        // TODO Auto-generated method stub
        createMineFields();
        time = (TextView) findViewById(R.id.tvTimer);
        tablelayout = (TableLayout) findViewById(R.id.tlMineFields);
        tvNoOfMines=(TextView) findViewById(R.id.tvNoOfMines);
        currentTime=0;
        check=0;
        isMineClicked = false;
        isClickedFirst = false;
        blockWidth = 10;
        blockHeight = 10;
        blockPadding = 5;
        noOfMineFields = 6;
        noOfMines = 1;
        noOfSafeFields=(noOfMineFields*noOfMineFields)-noOfMines;
        mineArray = new int[noOfMineFields][noOfMineFields];
        for (int i = 0; i < noOfMineFields; i++)
            for (int j = 0; j < noOfMineFields; j++)
                mineArray[i][j] = 0;
        mineWeight = new int[noOfMineFields][noOfMineFields];
        for (int i = 0; i < noOfMineFields; i++)
            for (int j = 0; j < noOfMineFields; j++)
                mineWeight[i][j] = 0;

        tablerow = new TableRow(this);
        timer= new Handler();
        timeElasped=new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                check=System.currentTimeMillis();
                currentTime++;
                time.setText(""+currentTime);
                timer.postAtTime(this, check);
                timer.postDelayed(timeElasped, 1000);
            }
        };
        tvNoOfMines.setText(""+noOfMines);
    }

【问题讨论】:

  • 哪一行对应Game.java:115?
  • 请评论该行,就像@NKN 建议的那样。我们还需要看看你是怎么调用这两个方法的,贴出相关代码吧。
  • @NKN 第 115 行对应 => buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth+(2*blockPadding)*noOfMineFields,blockHeight +(2*blockPadding)));

标签: android tablelayout


【解决方案1】:

我看到的问题是您在调用createMineFields() 函数之前 没有为noOfMineFields 变量设置固定值。我假设它是一个全局变量,但是您不知道在调用 createMineFileds() 时它所持有的值(很可能是 0,因为它是基于数字的默认值)。然后当你调用placeMineFields() 时,noOfMineFields 被设置为6 所以它超出了你的数组的范围(假设它最初是0

【讨论】:

  • 这非常有帮助。但是一旦在将值 6 分配给 noOfMineFields 后通过调用 createminefields() 清除了这个错误,我就会得到一个 ArithmeticException:divideByZero 异常。我在我的代码中使用任何算术运算可以抛出除零错误。XML 视图中的 stretchColumns='*' 有问题吗?我对此表示怀疑,因为我在 logcat 中遇到错误,例如 mutateColumnWidths
  • 这很令人费解。抱歉,我还有 12 小时的考试,所以我会在之后尝试解决它。现在不能浪费任何时间:(
【解决方案2】:

知道您的异常来自:

buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth+(2*blockPadding)*noOfMineFields,blockHeight +(2*blockPa‌​dding)));

您遇到的异常可能是因为 ij 的任何组合都未在您的 buttonBlock 数组中初始化。我建议在每次循环迭代的代码中添加 Log 元素,看看问题出在哪里(同时打印数组的当前大小可能会有所帮助)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2020-06-07
    • 2014-09-30
    • 2020-09-11
    • 2016-08-15
    相关资源
    最近更新 更多