Android-Bitmap-ImageView-Speicherverlust

Ich habe 4x4 imageView zu einer Aktivität hinzugefügt (BoardActivity), und der Benutzer kann die Bilder ändern, indem er darauf klickt. Mit HTC Desire (Android 2.2.2) habe ich OOM (Out of Memory) in ca. 30 Minuten intensiver Nutzung erhalten-EDIT: 16. Start dieser Aktivität-, aber kein anderes Gerät produziert dies (Android 2.1 und Android 2.2.1). Ist es möglich, dass ich bei der Verwendung von Bitmap / ImageView einen Fehler gemacht habe und dieser Fehler auftritt? Zuerst lade ich alle Ressourcen-IDs in eine Karte:

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);
//... I store 55 drawable's resourceId in this map

Dann ändere ich die Größe und speichere jedes Bild in einer Bitmap, dargestellt 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 {
        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;

        InputStream fis = getResources().openRawResource(resId);
        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();
    }
    return b;
}

Ich halte die imageViews in einem Array und initialisiere alle Bilder mit dieser Funktion:

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;
    }

Wenn ich ein Bild ändern muss, ändere ich einfach seine Ressource:

imageViews[i][j].setImageBitmap(imageBitmap.get("a"));

Und kurz bevor ich die Aktivität beende, recycle ich die Bitmap-Karte:

private void recycleImageBitmaps() {
    for (Bitmap b : imageBitmap.values()) {
        if (b != null) {
            b.recycle();
        }
    }

}

In AndroidManifest.xml habe ich diese Aktivität als "singleTask" deklariert:

<activity android:name=".game.board.BoardActivity" android:launchMode="singleTask">
    </activity>

In dieser Anwendung (Spiel) öffnen wir diese Aktivität mehrmals ... Was habe ich falsch gemacht? Kann dies den Fehler "Out of Memory" verursachen?

KORREKTUR Die getBitmapFromRes wurden folgendermaßen korrigiert:

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 stürzte immer noch beim 11. Start dieser Aktivität ab.

BEARBEITEN: Diese Aktivität (BoardActivity) wird über eine Aktivität (MenuActivity) gestartet, die über 4 Bildschaltflächen verfügt und sich in einer Tabhost-Aktivität befindet. Die imageButtons-Deklarationen sehen folgendermaßen aus:

<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"
     />

Wenn ich BoardActivity über MenuActivity starte, rufe ich nicht anfinish() bei MenuActivity und wenn ich anrufefinish() Bei der BoardActivity starte ich keine neue Absicht, daher kehre ich einfach zu der bereits geöffneten MenuActivity zurück. Und in den 16 Runden habe ich die OOM bekommen.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage