android - 具有“状态”设计模式的 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 对象,以及状态接口和具体状态(打开、关闭、预览、拍照)。
简单的草图:
相机上下文:
- 字段:包含设备、会话、特征、表面、处理程序、锁、请求构建器、回调(捕获、会话、设备)
- 方法:onOpenCamera、onCloseCamera、onCaptureCompleted
相机状态:
- 具体:OpenState、CloseState、PreviewState、TakingPhotoState
问题:
- 有人用camera2 api做PoC“状态”设计模式吗?这是可行的吗?
- 有没有人用并行计算(锁,线程)做状态设计模式?任何想法,教程,你有有趣的文章吗?
解决方案
好的,我准备好回答我的问题了。我已经完成了这个想法的 PoC。我为这样的事情编写了某种 SDK。而且我认为它是管理相机 2 api 调用的非常有用的库。我无法共享存储库,因为我已经为我的雇主完成了它(也许它最近会在 Internet 上可用)。但我可以分享一点知识。
作为项目的主要思想,我使用了“状态”设计模式(https://en.wikipedia.org/wiki/State_pattern),因为 FSA 分裂成许多部分很难维护。
所以我创建了以下状态:ClosedState
, OpenedState
, ConfiguredState
, PreviewState
, PreCapture
,Capture
和CaptureBurst
. 这CameraContext
是整个项目的主要课程。所有状态都继承自AbstractState
.
Closed
状态Opened
非常简单。几行代码,很具体。
Configured
刚开始预览。
PreviewState
具有捕获序列和捕获单张照片的功能(它调用 camera2session.capture
和session.captureBurst
session.
Capturing
顾名思义,各州负责拍照(capturestarted、capture completed 和 onimageavailable)
我的捕获状态,保存图像保护程序(或突发图像保护程序)的参考,并在 onimageavailable 调用期间被调用。
在此信息之后,是时候描述相机上下文了。您可能从 wikipedia 知道,它是所有呼叫的客户端。所以它有很多方法:openCamera、createSession、startPreview、captureStillPic、captureSequence。还有回调函数,onCameraOpen、onCameraClose、onImageAvailable、on 和 on,等等。其中一些方法只是特定于状态的方法的桥梁(CameraContext 的 onCameraOpen,是 ClosedState 的 onCameraOpen 的桥梁等)。
更重要的是,在 Camera2Api 中,我们有 4 个不同且非常重要的回调应该实现:CameraSessionCallback
、CameraStateCallback
和。因此,我创建了 StateAware 等效类,它们只是连接到 cameraContext 调用(的调用,调用的,等等)的桥梁。这些回调被传递给 Camera2API 对象。CameraCaptureCallback
ImageAvailableListener
onCameraOpen
StateAwareCameraStateCallback
onCameraOpen
CameraContext
onCameraOpen
ClosedState
此外项目包含ImageSavers
用于保存输出和FilenameGenerators
生成文件名。我还添加了某种后处理突发。使用仪器测试编写完整的 PoC,并且没有演示应用程序需要 1MM。拍摄突发图像的测试场景需要 100 - 150 行自定义代码(打开、配置、准备突发、拍摄突发、关闭),我认为这很容易理解/更改;)
推荐阅读
- python - 如何在不使用循环的情况下将一维列表转换为二维列表?
- javascript - Firestore Javascript 从 .get() 推送的数据在 .get() 函数之外无法访问
- mysql - Mysql GROUP BY 多个子句
- java - 如何在 JavaFX 上绘制网格并用点绘制网格角?
- javascript - 尽管一切都正确,mongoDB 方法仍返回 undefined
- ionic-framework - 是否有可以添加到 Ionic 项目的字符串或语言文件?
- java - 用 Java 编写我自己的 Wikipedia 查找和替换
- xrp - 为什么分类帐会使用其父分类帐的关闭时间进行散列?
- visual-studio-code - 如何显示 vscode 元数据页脚
- python - 为什么 numpy 导入的行为不同?