Android Camera中无法回调PictureCallback接口onPictureTaken()函数

近日在重构公司的相机相关应用的过程中(由于前辈的代码比较错乱,故而想重构),好了,引子就这么多了。在Camera的takePicture()碰到一个特别棘手的问题,就是始终无法回调onPictureTaken()函数。也就是以下的代码:

    mCamera.takePicture(null, null, mJpegPictureCallback);
@SuppressWarnings("deprecation")
    PictureCallback mJpegPictureCallback = new PictureCallback()
    // 对jpeg图像数据的回调,最重要的一个回调
    {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.e("TakePicture", "in take picture callback");
            if (null != data) {
                new Save(data).start();
            }
            ThreadUtils.showAllThread();
            stopPreview();
            LedUtils.closeLightLed();
        }
    };

而在前辈的项目中却可以执行到回调函数,之后就是google一下了,找了一通主要发现几点问题:(不局限于无法回调函数问题,通用于Camera问题)

1. camera资源是典型的C/S架构的服务,每次使用完毕需注意回收release()
2.预览很重要,在每次takePicture之前都要重新开启预览
3.preview的尺寸以及picture的尺寸要符合真机的标准,可以通过getSupportedPictureSizes来获取支持的size

经过上面的一番折腾,最重要的问题终于浮出水面了,问题是,我设定的picturesize是2592*1944的分辨率的照片,这是我的真机支持的最大的分辨率。运行一下,还是无法进行到回调函数中,而使用小一点的分辨率的size就可以进行到回调函数中。但是我检验前辈的camera参数中,picturesize也是最大的2592*1944,这就郁闷了啊!还是得借助stackoverflow以及google大神啊!主要得到以下两个观点:

1.camera.takePicture()函数是异步的,最好在确定照完相之后再进行回收操作,不然的话,你的相机可能还在拍照,就被回收了。原文地址看完这篇后,我仔细的在代码中寻找camera是否被回收操作了!然而可惜的是并没有。
/////despeared
2.真正让我醍醐灌顶的文章啊,具体就是,我们的应用内存使用过多,GC自动将 camera回收了,这就可以解释为什么将size的变小后就可以进行回调了,因为小分辨率的照片内存占用少,不会引起GC回收对象。而前辈的应用算是个demo吧,应用内存少!贡献大神地址
/////despeared

至此,感谢大神,按照他说的方式,终于成功的将图片设为了我想要的分辨率了!这次的填坑,给我的教训就是
当程序不报错,而又不能出现你想要的结果时,考虑内存使用情况!

过了很久再来看这篇文章,发现第二点是不正确,正如评论中大神的说法,硬引用是不会被GC回收的。答案还是在第一点。

你可能感兴趣的:(android,camera)