Dén*_*nes 6 android memory-leaks bitmap out-of-memory imageview
我将4x4 imageView放入活动(BoardActivity),用户可以通过单击更改图像.使用HTC Desire(Android 2.2.2),我在大约30分钟的密集使用中获得了OOM(Out Of Memory)-EDIT:此活动的第16次开始 -但是没有其他设备产生这个(android 2.1和android 2.2.1) ).是否有可能,我在bitmap/imageview使用中犯了一些错误并导致此错误?首先,我将所有资源ID加载到地图中:
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
Run Code Online (Sandbox Code Playgroud)
然后我调整大小并将每个图像保存到位图中,在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;
}
Run Code Online (Sandbox Code Playgroud)
我将imageViews保存在一个数组中,并使用此函数初始化所有图像:
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;
}
Run Code Online (Sandbox Code Playgroud)
当我需要更改图像时,我只需更改其资源:
imageViews[i][j].setImageBitmap(imageBitmap.get("a"));
Run Code Online (Sandbox Code Playgroud)
在我完成活动之前,我回收了位图贴图:
private void recycleImageBitmaps() {
for (Bitmap b : imageBitmap.values()) {
if (b != null) {
b.recycle();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在AndroidManifest.xml中,我将此活动声明为"singleTask":
<activity android:name=".game.board.BoardActivity" android:launchMode="singleTask">
</activity>
Run Code Online (Sandbox Code Playgroud)
在这个应用程序(游戏)中,我们多次重新打开这个活动......我错了什么?这会导致内存不足错误吗?
更正 更正这样的getBitmapFromRes:
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;
}
Run Code Online (Sandbox Code Playgroud)
HTC仍然在此次活动的第11次开始时坠毁.
编辑: 此活动(BoardActivity)从一个Activity(MenuActivity)启动,它有4个imageButton,并且处于Tabhost活动中.imageButtons声明如下所示:
<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"
/>
Run Code Online (Sandbox Code Playgroud)
当我从MenuActivity启动BoardActivity时,我不会finish()在MenuActivity上调用,当我finish()在BoardActivity 调用时,我没有启动新的intent,所以它只返回已经打开的MenuActivity.而这16轮,我得到了OOM.
为了减少内存,你可以试试这些东西:
编辑:基于注释中的对话:BitmapFactory.decodeStream(fis,null,o)返回的位图未分配给任何变量,因此不会被回收.Android 2.2和2.3将在这一行中出现泄漏.
| 归档时间: |
|
| 查看次数: |
14946 次 |
| 最近记录: |