首页 > 解决方案 > 具有“状态”设计模式的 Android Camera2 API

问题描述

我已经为不同的 Camera2 API 项目工作了 2 个月。你可能知道,Camera2 API 很难理解和维护,它需要一些多处理、状态和回调的知识。“只是”在谷歌示例上拍照的简单示例有 1000 行(https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment .java )。在互联网上,也有非常有前途的实现,称为 Camera3 https://github.com/QuinnFreedman/Camera3 - 它简化了 Camera2 的使用。

在我看到的几篇文章和示例中,Camera2 应用程序的核心部分是机器自动机 (FSA)。FSA 是可以的,但是随着它变大,很难理解、维护和扩展。恕我直言,解决方案是使用“状态”设计模式(https://en.wikipedia.org/wiki/State_pattern)。有保存状态的 Context 对象,以及状态接口和具体状态(打开、关闭、预览、拍照)。

简单的草图:

相机上下文:

相机状态:

问题:

  1. 有人用camera2 api做PoC“状态”设计模式吗?这是可行的吗?
  2. 有没有人用并行计算(锁,线程)做状态设计模式?任何想法,教程,你有有趣的文章吗?

标签: androiddesign-patternsandroid-camera2state-pattern

解决方案


好的,我准备好回答我的问题了。我已经完成了这个想法的 PoC。我为这样的事情编写了某种 SDK。而且我认为它是管理相机 2 api 调用的非常有用的库。我无法共享存储库,因为我已经为我的雇主完成了它(也许它最近会在 Internet 上可用)。但我可以分享一点知识。

作为项目的主要思想,我使用了“状态”设计模式(https://en.wikipedia.org/wiki/State_pattern),因为 FSA 分裂成许多部分很难维护。

所以我创建了以下状态:ClosedState, OpenedState, ConfiguredState, PreviewState, PreCapture,CaptureCaptureBurst. 这CameraContext是整个项目的主要课程。所有状态都继承自AbstractState.

Closed状态Opened非常简单。几行代码,很具体。

Configured刚开始预览。

PreviewState具有捕获序列和捕获单张照片的功能(它调用 camera2session.capturesession.captureBurstsession.

Capturing顾名思义,各州负责拍照(capturestarted、capture completed 和 onimageavailable)

我的捕获状态,保存图像保护程序(或突发图像保护程序)的参考,并在 onimageavailable 调用期间被调用。

在此信息之后,是时候描述相机上下文了。您可能从 wikipedia 知道,它是所有呼叫的客户端。所以它有很多方法:openCamera、createSession、startPreview、captureStillPic、captureSequence。还有回调函数,onCameraOpen、onCameraClose、onImageAvailable、on 和 on,等等。其中一些方法只是特定于状态的方法的桥梁(CameraContext 的 onCameraOpen,是 ClosedState 的 onCameraOpen 的桥梁等)。

更重要的是,在 Camera2Api 中,我们有 4 个不同且非常重要的回调应该实现:CameraSessionCallbackCameraStateCallback和。因此,我创建了 StateAware 等效类,它们只是连接到 cameraContext 调用(的调用,调用的,等等)的桥梁。这些回调被传递给 Camera2API 对象。CameraCaptureCallbackImageAvailableListeneronCameraOpenStateAwareCameraStateCallbackonCameraOpenCameraContextonCameraOpenClosedState

此外项目包含ImageSavers用于保存输出和FilenameGenerators生成文件名。我还添加了某种后处理突发。使用仪器测试编写完整的 PoC,并且没有演示应用程序需要 1MM。拍摄突发图像的测试场景需要 100 - 150 行自定义代码(打开、配置、准备突发、拍摄突发、关闭),我认为这很容易理解/更改;)


推荐阅读