当前位置: 代码迷 >> Android >> Bit地图对象回收不及时导致而内存溢出,求解?
  详细解决方案

Bit地图对象回收不及时导致而内存溢出,求解?

热度:50   发布时间:2016-04-28 02:47:57.0
Bitmap对象回收不及时导致而内存溢出,求解??
简述:



                                                                            (图一)


                                                                            (图二)



                                                                           (图三)
我的应用先是要读取300多张手机相册的图片,并依次装入Bitmap数组中,再以GridView形式显示在界面上(如图一丶二)。当摧毁这个activity时我调用了
	@Override
protected void onDestroy() {
super.onDestroy();
for (int i = 0; i < bmp.length; i++) {
if (bmp[i] != null) {
bmp[i].recycle();
bmp[i] = null;
}
}
System.gc();
}

这里回收Bitmap数组,但是当我跳往手机拍照activity时,按下快门得到数据并解析为Bitmap对象时就报了OOM的错误(如图三)


以下贴出相关代码:

1.根据手机图片的路径解析得到bitmap实例:
/**
 * 判断GridView是否停止滑动
 **/
private void isGridViewStop() {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;// 图片宽高都为原来的4分之一,即图片为原来的16分之一
gvSelect.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:// 滑动停止
for (; start_index < end_index; start_index++) {
try {
if (bmp[start_index] == null) {// 优化读取本地图片
bmp[start_index] = BitmapFactory.decodeFile(
imagePath[start_index], options);
// 对原位图进行缩放
bmp[start_index] = Bitmap.createScaledBitmap(
bmp[start_index], 165, 165, true);
}
} catch (Exception e) {
Log.d("空指针1", bmp[start_index] + "");

}
}
adapter.notifyDataSetChanged();
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 滚动
break;
default:
break;
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// 设置当前屏幕显示的起始index和结束index
start_index = firstVisibleItem;
end_index = firstVisibleItem + visibleItemCount;
}
});

}

2.按下快门,解析data得到bitmap实例

private final class TakePictureCallback implements PictureCallback {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
String sdStatus = Environment.getExternalStorageState();
if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) {
// 检测sd是否可用
Toast.makeText(PhotographActivity.this, "没有SD卡或SD卡不可用!",
Toast.LENGTH_LONG).show();
return;
} else {
Log.d("解码", "0*******");
// 解码指定字节数组中的一个不变的位图
bitmap = BitmapFactory.decodeByteArray(data, 0,
data.length);
Log.d("解码", "1*******");
Intent starEdit = new Intent(PhotographActivity.this,
ConfirmActivity.class);
startActivity(starEdit);
}
}
}



报错的Log日志:

01-09 15:48:47.564: I/Choreographer(20147): Skipped 50 frames!  The application may be doing too much work on its main thread.
01-09 15:48:50.567: I/Choreographer(20147): Skipped 68 frames!  The application may be doing too much work on its main thread.
01-09 15:48:50.778: D/解码(20147): 0*******
01-09 15:48:50.818: D/dalvikvm(20147): GC_FOR_ALLOC freed 257K, 74% free 16934K/64647K, paused 35ms, total 37ms
01-09 15:48:50.868: D/dalvikvm(20147): GC_CONCURRENT freed 10K, 50% free 48136K/95879K, paused 11ms+3ms, total 30ms

01-09 15:48:51.158: D/dalvikvm(20147): GC_FOR_ALLOC freed 2364K, 48% free 50168K/95879K, paused 31ms, total 31ms
01-09 15:48:51.198: D/dalvikvm(20147): GC_BEFORE_OOM freed 2K, 48% free 50165K/95879K, paused 39ms, total 39ms
01-09 15:48:51.198: E/dalvikvm-heap(20147): Out of memory on a 31961104-byte allocation.
01-09 15:48:51.198: I/dalvikvm(20147): "Thread-4040" prio=5 tid=13 RUNNABLE
01-09 15:48:51.198: I/dalvikvm(20147):   | group="main" sCount=0 dsCount=0 obj=0x42130508 self=0x68515be0
01-09 15:48:51.198: I/dalvikvm(20147):   | sysTid=20696 nice=0 sched=0/0 cgrp=apps handle=1751339088
01-09 15:48:51.198: I/dalvikvm(20147):   | schedstat=( 0 0 0 ) utm=5 stm=0 core=1
01-09 15:48:51.198: I/dalvikvm(20147):   at android.graphics.Bitmap.nativeCreate(Native Method)
01-09 15:48:51.198: I/dalvikvm(20147):   at android.graphics.Bitmap.createBitmap(Bitmap.java:650)
01-09 15:48:51.198: I/dalvikvm(20147):   at android.graphics.Bitmap.createBitmap(Bitmap.java:596)
01-09 15:48:51.198: I/dalvikvm(20147):   at app.takephoto.ConfirmActivity.savePhoto(ConfirmActivity.java:150)
01-09 15:48:51.198: I/dalvikvm(20147):   at app.takephoto.ConfirmActivity.access$7(ConfirmActivity.java:144)
01-09 15:48:51.198: I/dalvikvm(20147):   at app.takephoto.ConfirmActivity$2.run(ConfirmActivity.java:91)
01-09 15:48:51.198: I/dalvikvm(20147):   at java.lang.Thread.run(Thread.java:856)
01-09 15:48:51.198: E/dalvikvm(20147): threadid=13: exiting,name=Thread-4040
01-09 15:48:51.198: W/dalvikvm(20147): threadid=13: thread exiting with uncaught exception (group=0x416a2498)
01-09 15:48:51.198: E/AndroidRuntime(20147): FATAL EXCEPTION: Thread-4040
01-09 15:48:51.198: E/AndroidRuntime(20147): java.lang.OutOfMemoryError
01-09 15:48:51.198: E/AndroidRuntime(20147):  at android.graphics.Bitmap.nativeCreate(Native Method)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at android.graphics.Bitmap.createBitmap(Bitmap.java:650)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at android.graphics.Bitmap.createBitmap(Bitmap.java:596)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at app.takephoto.ConfirmActivity.savePhoto(ConfirmActivity.java:150)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at app.takephoto.ConfirmActivity.access$7(ConfirmActivity.java:144)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at app.takephoto.ConfirmActivity$2.run(ConfirmActivity.java:91)
01-09 15:48:51.198: E/AndroidRuntime(20147):  at java.lang.Thread.run(Thread.java:856)


很明显日志里进入了Log.d("解码", "0*******");,而没有进Log.d("解码", "1*******");。如果直接打开照相机拍照却又不会报OOM,所以我觉得应该是之前读取过多的图片,再去打开照相机拍照造成的OOM
,谢谢各位帮忙看看啦
------解决思路----------------------
onPictureTaken()函数里面
bitmap = BitmapFactory.decodeByteArray(data, 0,data.length); 
这里试试用Bitmap.Options压缩下
------解决思路----------------------
引用:
Quote: 引用:

额,朋友,我的意思是设置内存大小,方法,不记得,你百一下,因为我正在写代码用到imageloader,所以,就写了这几个词.
不过,如果你有大量图片下载或从本地读取,都可以用imageloader,它可以设置memoryCacheSize.


很遗憾经过上午的调试ImageLoader运用后,先成功的展示了手机相册里的图片,但跳往拍照界面后按下快门的瞬间  仍旧抛出了OOM。目前就只有用Bitmap.Options压缩下是试试了



那你就只有用这个了.
  相关解决方案