I put a 4x4 imageView in the action (BoardActivity) and the user can change the images by clicking them. With HTC Desire (Android 2.2.2), I got OOM (Out Of Memory) in about 30 minutes of intensive use -EDIT: the 16th launch of this operation is , but no other devices do this (android 2.1, android 2.2.1) . Is it possible that I made some mistake using a bitmap / image and what causes this error? First, I load the entire resource identifier into the map:
private Map<String, Integer> imageResourceMap; imageResourceMap = new HashMap<String, Integer>(); imageResourceMap.put("a", R.drawable.a); imageResourceMap.put("b", R.drawable.b); imageResourceMap.put("c", R.drawable.c);
Then I resize and save each image into a bitmap presented in Map:
private static Map<String, Bitmap> imageBitmap; private void loadBitmaps(int imagesSize) { for (String s : imageResourceMap.keySet()) { Bitmap tmp = getBitmapFromRes(imageResourceMap.get(s), imagesSize); imageBitmap.put(s, tmp); } } private Bitmap getBitmapFromRes(int resId, int imageSize) { Bitmap b = null; try {
I save ImageViews in an array and run all the images using this function:
private static ImageView[][] imageViews; private ImageView getImage(String name) { MyImageView item = new MyImageView(this, i, j, c + ""); item.setImageBitmap(imageBitmap.get(name)); item.setAdjustViewBounds(true); return item; }
When I need to change the image, I just change its resource:
imageViews[i][j].setImageBitmap(imageBitmap.get("a"));
And before I finish the action, I process the bitmap map:
private void recycleImageBitmaps() { for (Bitmap b : imageBitmap.values()) { if (b != null) { b.recycle(); } } }
In AndroidManifest.xml, I declared this activity "singleTask":
<activity android:name=".game.board.BoardActivity" android:launchMode="singleTask"> </activity>
In this application (game), we re-open this activity several times ... What am I wrong? Could this cause a "Out of Memory" error?
CORRECTION Fixed the getBitmapFromRes action as follows:
private Bitmap getBitmapFromRes(int resId, int imageSize) { Bitmap tmp = null; Bitmap b = null; try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; InputStream fis = getResources().openRawResource(resId); tmp = BitmapFactory.decodeStream(fis, null, o); fis.close(); int scale = 1; if (o.outHeight > imageSize || o.outWidth > imageSize) { scale = (int) Math.pow(2, (int) Math.round(Math.log(imageSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5))); } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; fis = getResources().openRawResource(resId); b = BitmapFactory.decodeStream(fis, null, o2); fis.close(); } catch (IOException e) { e.printStackTrace(); }finally{ if(tmp != null){ tmp.recycle(); tmp = null; } } return b; }
HTC still crashed on the 11th launch of this operation.
EDIT: This action (BoardActivity) is launched from Activity (MenuActivity), which has 4 imageButton, and works in Tabhost. ImageButtons declarations are as follows:
<ImageButton android:id="@+id/game_menu_CreateButton" android:layout_width="120dip" android:layout_height="120dip" android:layout_alignRight="@+id/textView1" android:layout_alignTop="@+id/textView1" android:background="@drawable/create" android:layout_marginRight="1sp" android:layout_marginTop="10sp" />
When I launch BoardActivity from MenuActivity, I do not call finish() in MenuActivity, and when I call finish() in BoardActivity, I do not start a new intention, so it just goes back to the already open MenuActivity. And in the 16th round of this, I got OOM.