【问题标题】:android camera classic API: writing a blocking (synchronous) 'takePicture()'android相机经典API:编写阻塞(同步)'takePicture()'
【发布时间】:2018-02-12 13:37:58
【问题描述】:

我正在编写一个 Android 应用程序,我需要拍照。使用标准教程,我大部分时间都可以很快地工作。但我需要编写一个阻塞版本的“takePicture()”。我正在尝试重新设计我的设计,以便一切都异步完成,但代码最终只是意大利面条代码,因为很多任务都依赖于前一个任务的完成。我曾预计拍照将花费不到一秒钟的时间。所以我认为有一个阻塞(同步)“takePicture()”是一个合理的目标。

所以我在 UI 线程中创建了一个摄像头(我是 Android 新手,但我认为在 UI 线程中调用了 'onCreate()' 等)。我还打开相机并在 UI 线程中释放它。我还在 UI 线程中调用“takePicture()”。我尝试轮询“volatile byte[] jpeg;”字段变为非空,带有“while (jpeg != null) sleep(1000);”但它永远不会被分配。令我惊讶的是,直到我通过“onClick()”函数时,我的回调才会被调用——“takePicture()”似乎没有触发任何东西,它只是排队一些东西,据我所知。

我的下一次尝试涉及在“ExecutorService.newSingleThreadExecutor()”中完成所有相机工作(打开、拍摄、发布),但这也没有成功。即使我这样做(见下文),在应用程序完成“onClick()”之前不会调用回调。

public byte[] takePhoto()
{
    if (camera == null)
        return null;
    cameraThreadService.submit(new Runnable() {
        @Override
        public void run() {
            Camera.PictureCallback mPicture = new Camera.PictureCallback() {

                @Override
                public void onPictureTaken(byte[] data, Camera camera) {
                    jpeg = data;
                }
            };
            camera.takePicture(null, null, mPicture);
        }
    });
    int n = 0;
    while (jpeg == null) {
        sleep(1000);
        if (n++ > 5)
            break;
    }
    return jpeg;
}

谁能告诉我如何编写阻塞(同步)'camera.takePicture()'?

【问题讨论】:

    标签: android multithreading camera


    【解决方案1】:

    令我惊讶的是,直到我退出“onClick()”函数后,我的回调才会被调用——“takePicture()”似乎没有触发任何东西,它只是尽可能地排队一些东西想办法。

    您的onPictureTaken() 在主应用程序线程上被调用。主应用程序线程不能同时做两件事。在您从onClick() 返回之前,无法调用onPictureTaken()

    谁能告诉我如何编写阻塞(同步)'camera.takePicture()'?

    这是不可能的,抱歉。

    【讨论】:

    • "cameraThreadService.submit(new Runnable() { ...." 似乎暗示它没有在主线程上调用。
    • 你是说不可能“睡眠和循环”,即在满足特定条件之前进行轮询?我不会告诉我的雇主“这是不可能的”。
    • “触发”是什么意思,在“takePicture()”的官方文档中:“触发异步图像捕获。” ……?如果我理解这在线程方面的含义可能会更有意义。
    • @TimCooper:“你是说不可能“休眠并循环”,即在满足特定条件之前进行轮询? - 不在你的场景中。此外,这首先不是一个特别好的编程实践。 “如果我理解这在线程方面的含义可能更有意义”——在主应用程序线程上调用takePhoto()onPictureTaken() 将在主应用程序线程上调用。一个线程不能同时做两件事。
    • @TimCooper:“似乎暗示它没有在主线程上调用”——假设cameraThreadService.submit() 在后台线程上调用它的Runnable,所做的只是调用takePicture()在后台线程上。它没有说明onPictureTaken() 的调用位置。
    猜你喜欢
    • 2016-04-05
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    • 2023-03-14
    • 2013-07-20
    相关资源
    最近更新 更多