The problem I see is that you do not set a fixed value for noOfMineFields
variable before you call createMineFields()
function. I assume it is a global variable, but you have no knowledge of what value it holds when createMineFileds()
is called (most likely 0
since it's default number-based value). Then when you call placeMineFields()
, the noOfMineFields
is set to 6
so it goes beyond the scope of your array (assuming it was initially 0
)
ArrayOutOfBoundException while creating button array
-
29-09-2022 - |
题
I am developing a game that requires rows and columns of buttons.I really cant figure out how ArrayIndexOutOfBound exception occurs in my code.Help me figure out the error.Thank you
this is my XML view
<?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>
this is the part of my code where I access the button array
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)));
}
}
Im calling the createMineFields() field first followed by placeMineFields().Im new to android and programming.Help me figure out where and how ArrayIndexOutOfBound exception happens.
this is the Error that was issued in 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
this is the code where I call createminefields() and 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);
}
解决方案
其他提示
After knowing your exception comes from the:
buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth+(2*blockPadding)*noOfMineFields,blockHeight +(2*blockPadding)));
The exception you're getting is probably because any i
and j
combination is not initialized in your buttonBlock
array. I recommend putting Log
elements in your code for each loop iteration and see where is the problem (also printing the current sizes of your array may help).