我正在制作棋盘游戏,并且我正在为棋盘使用 10x10 GridView。我制作了一个类 ImageAdapter 扩展 BaseAdapter ,它包含一个整数图标数组(9 个补丁文件),这些用于显示棋盘方格的图像。这些图标存储在 res/drawable 文件夹中,大小为 629X629,平均大小约为 5 KB。
我的 ImageAdapter 类具有以下 getView() 方法,该方法实质上回收了相同的视图以节省内存:
编辑:(我已经包含了在游戏的 Activity 中调用的 changeIcon 方法)
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) { // if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
}
else{
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
public void changeIcon(int x, int y, Integer icon){
int position = (9-y)*10 + x;
mThumbIds[position] = icon;
getView(position, currentView, null);
}
我有一个名为 Game 的单独类,其中处理游戏的逻辑。我将棋子存储在 Piece[][] 数组中,其中 Piece 是我创建的另一个类,用于保存(你猜对了)游戏棋子的数据。相关的是处理棋子移动的方法 move(int xFrom, int yFrom, int xTo, int yTo)。我可以整天移动碎片,一切都很好。
但是,一旦我将一块移到另一块中,应用程序就会崩溃。预期的行为是创建一个新片段。发生这种情况的代码如下:
public boolean move(int xFrom, int yFrom, int xTo, int yTo){
boolean success = false;
Piece pieceToMove = getPiece(xFrom,yFrom);
Piece pieceAtDest = getPiece(xTo,yTo);
int moveTeam = pieceToMove.getTeam();
if(isLegalMove(xFrom, yFrom, xTo, yTo, pieceToMove)&&(turn == moveTeam)){
if( pieceAtDest == null)
{
/*I do something when the destination piece is null;
this block causes no problems */
}
else{
success = true;
pieceToMove.merge();
position[xTo][yTo] = pieceToMove;
position[xFrom][yFrom] = null;
}
}
return success;
}
所以,有问题的调用是pieceToMove.merge()。Piece 类中的方法 merge() 只是简单地更改该类中的字段类型(片段变成新的),然后调用该类的方法 setIcon()。该方法根据类型的值设置类的图标字段。而且,如上所述,图标是整数,指的是 res/drawable 中的九个补丁文件。
最后,从Activity GameBoardActivity 调用move(int xFrom, int yFrom, int xTo, int yTo) 方法,移动成功后Activity 要求ImageAdapter(称为adapter)重绘棋盘,如下:
boolean success = game.move(xFrom,yFrom,xTo,yTo);
if(success){
Integer destIcon = game.getPiece(xTo, yTo).getIcon();
Piece pieceAtDep = game.getPiece(xFrom, yFrom);
Integer depIcon;
if(pieceAtDep == null)
depIcon = R.drawable.square;
else
depIcon = game.getPiece(xFrom, yFrom).getIcon();
adapter.changeIcon(xTo,yTo,destIcon);
adapter.changeIcon(xFrom,yFrom,depIcon);
gridView.setAdapter(adapter);
}
Logcat 说导致“致命信号 11”和“6330272 字节分配内存不足”的行imageView.setImageResource(mThumbIds[position]);
是 ImageAdapter 的 getView 方法中的行。
所以,就像我说的,一切都很好,直到我需要合并两个部分,然后我得到内存不足的错误。还值得注意的是,这种合并行为在应用程序的早期迭代中运行良好。
我现在应该提到标准免责声明,因为我是一个在 java/android 中编码的完整初学者,并且我已经查看了与类似问题相关的其他问题,但似乎没有其他人以与我相同的方式处理他们的位图是。
任何帮助是极大的赞赏。非常感谢。
更新
通过进一步的测试,我注意到另一个奇怪之处,即有时会出现问题,有时不会,我无法确定在某些情况下导致崩溃的原因,而在其他情况下则不会。更准确地说,执行完全相同的移动顺序可能会也可能不会导致崩溃。这是相当神秘的。