分享

Camera.PictureCallback不执行 | fynas

 QCamera 2015-02-14

android开发中调用camera api来操作相机比起直接使用intent方式调用拍照程序可以让我们更灵活地进行拍照,或者是自动拍照。具体的camera api的使用方式和代码这里就不贴了,网上有很多现成的。最近在一个应用中实现自动对焦并自动拍照功能,出现了一个问题,几经折腾终于解决,分享出来,希望给和我一样遇到这个问题的人有所帮助。

  • 问题现象:

Camera.takePicture运行后方法有时无法回调Camera.PictureCallback,直接运行时出现该问题的机率很大,而连接eclipse在debug模式下一般没问题,takePicture代码如下;

1
camera.takePicture(shutterCallback, null, pictureCallback);

 

  • 问题原因分析:

之前有过一些经验,直接运行有问题,而调试模式下没问题的情况,一般这个问题都和程序执行代码的快慢有关系。因此,先尝试在该回调的前一步加sleep,即在按下快门回调时书写如下代码:

1
2
3
4
5
6
7
8
9
10
11
ShutterCallback shutterCallback = new ShutterCallback() {
@Override
public void onShutter() {
try {
Thread.sleep(1000);//sleep 1秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};

再运行,果然每次都能成功执行回调pictureCallback。虽然看起来像是解决了问题,但是这样只是治标不治本,谁愿意在自己的代码里随便sleep呢。继续找原因,因为在调试模式下无法复现该问题,所以只能在每一行代码执行完后都在LogCat中打出日志来看。仔细观察发现,在每次调用完shutterCallback之后,都会立刻打出一条如下日志:

04-04 16:54:40.810: I/dalvikvm-heap(18804): Grow heap (frag case) to 13.091MB for 6291472-byte allocation

再看看自己的代码,使用的camera对象是在一个方法里定义的局部变量,很可能是在回调pictureCallback前camera对象被GC回收了。于是上stackoverflow这个神器上去找找,也有人遇到这个问题,并且说把camera对象变成强引用就行。于是我以activity类的私有变量来持有camera对象:

1
private Camera camera;

然后去掉上面添加的sleep,再运行应用,问题解决了。

  • 解决方案

通过上面的分析,我们得出解决该问题的两种解决方案:

  1. 在ShutterCallback中sleep一定时间;
  2. 强引用camera对象;

第1种方法肯定是不推荐了,第2种方法也有它的问题,干拢了GC的工作,有一定可能会导致OOM而使应用崩溃。从分析来看有可能是拍出的照片过大导致内存使用猛增触发了GC工作,因此如果可以接受的话可降低拍照图片质量来改进应用的内存使用。如果你还有更好的解决方案,欢迎在下面留言讨论。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多