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回收的。答案还是在第一点。

在编程,使用同一个回调函数实例来处理多个相机的事件是一种常见的设计模式。这种方式可以减少代码的重复,并且使得回调逻辑的维护和更新更加集和方便。以下是如何实现这一设计的简要说明: 1. **定义回调函数**:首先,需要定义一个回调函数,该函数能够处理来自不同相机的事件。这个函数一般会包含一个参数,用于标识是哪个相机触发了事件,这样在回调函数内部就可以根据不同的相机执行不同的逻辑。 2. **注册回调函数**:在设置相机时,将同一个回调函数实例注册给所有需要监听事件的相机。这样,无论是哪个相机触发了事件,都会调用这个回调函数。 3. **区分相机**:在回调函数内部,通常会有一个机制来识别是哪个相机触发了事件。这可能通过传递给回调函数的参数来实现,或者通过其他方式(如全局变量、事件对象的属性等)来区分。 4. **处理事件**:在回调函数,根据识别出的相机来执行相应的处理逻辑。每个相机可能会有不同的事件处理逻辑,这就需要在回调函数内部进行判断并调用相应的代码块。 例如,在Android开发,多个相机使用同一个`Camera.PictureCallback`实例来处理拍照事件: ```java Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 这里通过camera参数或者其他方式来识别是哪个相机触发的事件 if (camera.equals(camera1)) { // 处理camera1的拍照事件 } else if (camera.equals(camera2)) { // 处理camera2的拍照事件 } } }; // 在设置相机时注册回调函数 camera1.setPictureCallback(mPictureCallback); camera2.setPictureCallback(mPictureCallback); ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值