I am making a board game and I am using a 10x10 GridView for the board. I created an ImageAdapter class that extends the BaseAdapter, which contains an array of Integer icons (9 patch files), and they are used to display images for the squares of the board. The icons are stored in the res / drawable folder, are 629X629 in size, and have a size of about 5 KB.
The My ImageAdapter class has the following getView () method, which essentially processes the same view to save memory:
EDIT : (I have included the changeIcon method, which is called in the Activity for the game)
public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { // if it 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); }
I have a separate class called "Game", which processes the logic of the game. I store the pieces in the Piece [] [] array, where Piece is another class I made to store data (you guessed it) in parts of the game. Relevance is the move method (int xFrom, int yFrom, int xTo, int yTo) that handles the movement of shapes. I can move the pieces all day, and everything is fine.
However, as soon as I move one part to another, the application crashes. The supposed behavior is that a new part is created. The code where this happens is below:
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; }
So an abusive call is partToMove.merge (). The merge () method in the Piece class simply changes the type field in this class (the piece becomes something new), and then calls the setIcon () method of this class. This method sets the class icon field depending on the type value. And, as mentioned above, the icons are integers referring to nine patch files in res / drawable.
Finally, the action method (int xFrom, int yFrom, int xTo, int yTo) was called from the Activity GameBoardActivity, and after successfully moving the Activity, it requests an ImageAdapter (called an adapter ) to redraw the board as follows:
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 says the line leading to "Fatal Signal 11" and "Out of memory when distributed over 6330272 bytes" is the line imageView.setImageResource(mThumbIds[position]); in the getView method of the ImageAdapter.
So, as I said, everything goes well until I need to combine the two parts, then I get an error from memory. It's also worth noting that this merge behavior worked fine in an earlier iteration of the application.
Now I have to mention the standard disclaimer that I start when it comes to coding in java / android, and that I looked at other issues related to similar problems, but no one seems to handle their bitmaps in the same way as I am.
Any help is appreciated. Thank you very much.
UPDATE
In the course of further testing, I noticed another oddity, which is that sometimes a problem arises, and sometimes not, and I canโt determine what causes failures in some cases, and not others. More precisely, the execution of the same sequence of moves may or may not lead to failure. This is pretty cryptic.