简述:
(图一)
(图二)
(图三)
我的应用先是要读取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压缩下
------解决思路----------------------
那你就只有用这个了.