【问题标题】:Android Camera won't take picture depending on what is after it in codeAndroid Camera 不会根据代码中的内容拍照
【发布时间】:2012-03-18 22:10:59
【问题描述】:

我尝试使用以下代码拍照并将照片的一些信息保存到数据库中。数据库部分已经过彻底测试,在所有其他情况下都可以正常工作。不幸的是,如果我取消注释下面的注释代码,我的代码就会超时。出于某种原因,如果this.camera.takePicture() 方法后面有代码,takePicture() 根本不会调用被覆盖的onPictureTaken 方法(它应该做的第一件事是打印出一行文本,但它没有'甚至不这样做)。如果后面没有代码,它可以正常工作。

在安装闩锁之前,我会收到一个错误,因为 ph.getPhoto() 正在返回 nullonPictureTaken() 尚未设置 ph 的 .photo 成员变量,因为它尚未被调用)。安装闩锁后,它会一直等到超时(或永远,如果没有指定超时值)。

谁能告诉我我错过了什么?

    public void takePicture(View view) throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        System.out.println("Taking Photo!");
        PhotoHandler photoHandler = new PhotoHandler(getApplicationContext(),latch);
        this.camera.takePicture(null, null, photoHandler);

    /* PhotoHandler has an overridden "onPictureTaken()" method which releases the latch as its final
     * action; however, its first instruction is to print a confirmation that it has been accessed.
     * Unfortunately, for some reason, onPictureTaken() is not called if the following code is
     * uncommented; it deadlocks for the five seconds before timing out. However, with out the following,
     * the camera.takePicture method invokes onPictureTaken() and it works just fine. */


//      latch.await(5,TimeUnit.SECONDS);
//      DatabaseHandler db = new DatabaseHandler(this);
//      Photo p = photoHandler.getPhoto();
//      db.addPhoto(p);
//      List<Photo> photos = new ArrayList<Photo>();
//      photos.add(p);
//      this.addPhotosToMap(photos);
}

【问题讨论】:

    标签: android multithreading concurrency camera deadlock


    【解决方案1】:

    onPictureTaken() (afaik) 在主 / UI 线程上执行。如果您的takePicture 方法也在那里被执行,那么它一定会发生,因为线程不能等待自己。

    此外,您不得阻塞主线程,否则您的 Activity 将 ANR。

    如果您将注释代码(减去该锁存器)移动到onPictureTaken(),那么一切都应该没问题。那些onSomethingHappened 回调正是为该任务而制作的

    【讨论】:

    • takePicture 方法是主要活动的一部分,由按钮执行。我不知道如何检查它属于哪个线程。我同意它应该发生;但是,就像我说的那样,除非删除代码的后半部分,否则它不会发生。它甚至不执行第一条指令,这是一个简单的 sysout。其次,我知道我不应该阻塞线程,但是 getPhoto() 方法不应该在设置照片的方法之前执行。我可以稍后移动它或完全移除闩锁,但这并不能解决我现在的问题。
    • 第三,我最初在onPictureTaken() 中有数据库代码,但它也不喜欢那样,所以我移动它以试图找出问题所在。我可以把它移回来,但它不能解决问题。无论如何,除了数据库内容之外,当前注释掉的其余代码负责用新照片的标记填充地图视图。那不应该是 UI 的一部分吗?如果没有,我应该如何告诉 onPictureTaken 来操作 UI?
    • onPictureTaken 在拍照之前不会执行。您知道它是在调用该方法时发生的(就像您知道一旦获得onClick 就按下了按钮)。由于回调是在主线程上执行的,因此您可以简单地从那里为 UI 设置图像。 onPictureTaken 是 UI 部分。您修改 UI 的方式与您在例如onCreate(本身就是这样一个回调)
    • 我重写了程序以在 Activity 的 takePicture 方法而不是 onPictureTaken() 中生成文件路径,以完全避免这个问题(我永远不必从 onPictureTaken 中获取任何信息)。我仍然在 onPictureTaken() 中做文件系统工作并且没有问题,所以它与文件系统的速度无关(无论如何,将一个小图像文件写入 SD 卡应该不会花一分钟,所以文件 I /O 不会导致问题)。
    【解决方案2】:

    将所有后处理(即您已注释掉的代码)放入适当的回调中,而不是在 takePicture 之后。并将文件系统访问等慢速操作放入后台线程(例如 AsyncTask)。

    【讨论】:

    • 大部分后期处理负责更改 UI。我最初将 db 代码作为 onPictureTaken() 方法的一部分,但我将其移出以查看是否是问题的原因。我可以把它放回去,但它不会解决我的问题。无论如何,我可以立即执行所有文件系统的东西——这不是问题 atm(尽管感谢你的建议)——代码的后半部分被注释掉了。为什么camera.takePicture()之后的代码会影响它是否回调onPictureTaken()
    • 可能代码正在运行,但有错误。在图片数据准备好之前,可能会到达该代码。
    • 好的,5 秒后,可能不会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多