Out of memory error setImageResource

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.

+4
source share
1 answer

IDs are available in your mThumbIds code. What you need to do is create a thumbnail of a particular image by executing the following code.

 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; } public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } 

Use this code,

 decodeSampledBitmapFromResource(getResources(),R.drawable.xyz, 100, 100); 

Here you can specify a sample size of 100 * 100. This way a thumbnail of this size will be created.

+6
source

All Articles