【问题标题】:GC cleaning the object before calling onPictureTaken method在调用 onPictureTaken 方法之前 GC 清理对象
【发布时间】: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


【解决方案1】:

我发现问题出在我的方法 (takePicture) 上,在调用 onPictureTaken 之前该方法已关闭。我解决了在 takePhoto 方法中延迟的问题。

【讨论】:

    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2018-10-07
    • 2011-03-25
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多