【发布时间】:2015-06-08 21:09:24
【问题描述】:
我开发了一个应用程序,可以在不向用户预览照片的情况下拍摄照片。我的问题是在执行 OnPictureTaken 方法之前,有时 GC 会清理由方法 Camera.takePicture() 创建的对象。因此,当它发生时,应用程序无法保存该照片。
这是拍照的班级:
public class MyCamera implements Camera.PictureCallback {
private Camera mCamera;
private Context context;
public MyCamera(Context c_) {
Log.d(TAG, "On constructor");
context = c_;
if (Camera.getNumberOfCameras() >= 2) {
mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
} else {
mCamera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
}
}
public void takePicture() {
try {
Log.d(TAG, "On take picture");
mCamera.setPreviewTexture(new SurfaceTexture(0));
mCamera.startPreview();
Thread.sleep(1000);
Log.d(TAG, "About to take");
mCamera.takePicture(null, null, null, this);
Log.d(TAG, "Took it");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d(TAG, "onPictureTaken");
File pictureFile = getOutputMediaFile(1);
if (pictureFile == null) {
Log.d(TAG, "Error creating picture file");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (Exception e) {
Log.d(TAG, "Error writing picture");
e.printStackTrace();
}
finally {
mCamera.release();
}
}
我尝试将回调更改为全局变量或将其用作我的类的实现,但是它们都没有顺利运行。
这里是 logCat:
06-08 15:46:48.554: D/MyAppService(1248): Capture camera this time
06-08 15:46:48.554: D/MyCamera(1248): On constructor
06-08 15:46:48.844: D/MyCamera(1248): On take picture
06-08 15:46:49.884: D/MyCamera(1248): About to take
06-08 15:46:49.884: D/MyCamera(1248): Took it
06-08 15:46:51.844: D/MyCamera(1248): onPictureTaken
06-08 15:46:51.854: D/DataReceive(1248): handling data
06-08 15:46:51.854: E/DataReceive(1248): Data handled
06-08 15:48:12.144: D/dalvikvm(1248): GC_FOR_ALLOC freed 479K, 3% free 17161K/17676K, paused 41ms, total 42ms
06-08 15:48:48.164: D/dalvikvm(1248): GC_EXPLICIT freed 104K, 3% free 17165K/17676K, paused 9ms+2ms, total 46ms
06-08 15:48:48.604: D/MyAppService(1248): Capture camera this time
06-08 15:48:48.604: D/MyCamera(1248): On constructor
06-08 15:48:48.884: D/MyCamera(1248): On take picture
06-08 15:48:49.914: D/MyCamera(1248): About to take
06-08 15:48:49.914: D/MyCamera(1248): Took it
06-08 15:48:51.884: D/dalvikvm(1248): GC_FOR_ALLOC freed 8K, 3% free 17163K/17676K, paused 16ms, total 16ms
06-08 15:48:52.634: I/dalvikvm-heap(1248): Grow heap (frag case) to 17.046MB for 266152-byte allocation
06-08 15:48:52.644: D/dalvikvm(1248): GC_FOR_ALLOC freed <1K, 3% free 17423K/17936K, paused 10ms, total 10ms
【问题讨论】:
-
为什么你认为被GC释放的是你图片的
data? -
因为每次执行 GC 时,我都没有收到日志消息说 onPictureTaken 正在执行。例如,您可以注意到有一条消息“D/MyCamera(1248): onPictureTaken”,然后是以下消息:“06-08 15:46:51.854: D/DataReceive(1248): handling data”和“06 -08 15:46:51.854: E/DataReceive(1248): 数据处理”。执行 GC 时,我没有收到这些消息。
-
您是否认为
takePicture()只是失败了?你没有检查它的返回值。 -
可能是因为您在回调结束时释放了相机对象?在任何时候,都没有理由假设 GC 导致了这种情况。这似乎只是导致内部缓冲区被释放的失败的副作用。
-
感谢您的帮助,Kichik。我尝试删除释放相机对象的代码,但没有奏效。我仍然面临这个问题。每拍摄五张照片,当 LogCat 上出现以下消息时,一张失败: 06-09 10:52:04.194: D/dalvikvm(9747): GC_FOR_ALLOC freed 8K, 3% free 17140K/17652K, paused 16ms, total 17ms 06 -09 10:52:04.194: I/dalvikvm-heap(9747): 将堆(碎片情况)增加到 17.009MB,分配 250953 字节
标签: android garbage-collection picturecallback