Android的位图ImageView的内存泄漏位图、内存、Android、ImageView

由网友(情感洁癖)分享简介:我把4×4 ImageView的一个活动(BoardActivity),并且用户可以通过单击它们改变图像。随着HTC Desire的(安卓2.2.2),我在大约30分钟的密集使用率 - 编辑了OOM(内存不足):本次活动的第16届开始 - ,但不允许其他设备产生这样的(机器人2.1和Android 2.2.1)。是...

我把4×4 ImageView的一个活动(BoardActivity),并且用户可以通过单击它们改变图像。随着HTC Desire的(安卓2.2.2),我在大约30分钟的密集使用率 - 编辑了OOM(内存不足):本次活动的第16届开始 - ,但不允许其他设备产生这样的(机器人2.1和Android 2.2.1)。是否有可能,我做了一些错误的位图/ ImageView的使用率,并导致此错误? 首先,我加载所有资源ID成图:

I put 4x4 imageView to an activity(BoardActivity), and 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 useage - 16th start of this activity-, but no other devices produces this (android 2.1, and android 2.2.1). Is it possible, that I made some mistake with the bitmap/imageview useage and that causes this error? First, I load all resource ID into a 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);
//... I store 55 drawable's resourceId in this map

于是我调整,每一个图像保存为位图,psented在地图重新$ P $:

Then I resize and save every image into bitmap, represented 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;
}

我一直在数组中的imageViews,并初始化使用此功能的所有图片:

I keep the imageViews in an array, and init all images with 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 an image, I simple change its resource:

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

和权利之前,我完成了活动,我回收位图:

And right before I finish the activity, I recycle the bitmap map:

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

}

在AndroidManifest.xml中我宣布本次活动singleTask:

In AndroidManifest.xml I declared this activity "singleTask":

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

在此应用程序(游戏),我们重新开始这一活动的几次... 我是怎么了?可这会导致内存不足的错误?

In this application(game), we reopen this activity a several times... What did I wrong? Can this cause the Out Of Memory error?

修正 更正了getBitmapFromRes是这样的:

CORRECTION Corrected the getBitmapFromRes like this:

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仍然坠毁本次活动的第11个开始。

HTC still crashed at the 11th start of this activity.

编辑: 从活动(MenuActivity)本次活动(BoardActivity)推出,其中有4个ImageButton的,并且是一个Tabhost活动。该imageButtons的声明是这样的:

This activity(BoardActivity) launch from an Activity(MenuActivity), which have 4 imageButton, and is in a Tabhost activity. The imageButtons declarations look like this:

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

当我开始从MenuActivity的BoardActivity,我不叫完成()在MenuActivity,当我打电话完成()在BoardActivity,我不开始新的意图,所以它只是返回到已经打开的MenuActivity。而16轮,我得到了OOM。

When I start the BoardActivity from MenuActivity, I don't call finish() at MenuActivity, and when I call finish() at the BoardActivity, I don't start a new intent, so it just return to the already opened MenuActivity. And the 16 round of this, I got the OOM.

推荐答案

要减少内存,你可以尝试这些东西:

To reduce memory, you can try out these things :

将可绘制成位图后,您可以设置imageResourceMap为null。这将卸载3可绘制。 避免存储参考imageViews。你可能会存储imageViews它们是从UI 删除,即使 在更多的时候回收的位图。而不是仅仅的onDestroy的,只要你知道,没有使用一个位图,您可以循环再利用。

编辑:基于所述会话中的注释:由BitmapFactory.de codeStream返回的位图(FIS,空,邻)不分配给任何变量,因此是不回收。 Android的2.2和2.3将有泄漏此行。

Edit : based on the conversation in the comments : The bitmap returned by BitmapFactory.decodeStream(fis, null, o) is not assigned to any variable and hence is not recycled. Android 2.2 and 2.3 will have leaks in this line.

阅读全文

相关推荐

最新文章