Android Camera2 API 具有 "State" 设计模式

Android Camera2 API with "State" Design Pattern

我已经为不同的 Camera2 API 项目工作了 2 个月。如您所知,Camera2 API 理解和维护起来并不困难,它需要一些多处理、状态和回调方面的知识。 "just" 在 google 示例上拍照的简单示例有 1000 行(https://github.com/googlesamples/android-Camera2Basic/blob/master/Application/src/main/java/com/example/android/camera2basic/Camera2BasicFragment.java). In the internet, there is also very promissing implementation, called Camera3 https://github.com/QuinnFreedman/Camera3 - 这简化了 Camera2 的使用。

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

简图:

CamerContext:

相机状态:

问题:

  1. 有人用 camera2 api 做过 PoC "State" 设计模式吗?这可行吗?
  2. 有没有人用并行计算(锁,线程)做状态设计模式?有什么想法,教程,你有有趣的文章吗?

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

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

所以我创建了以下状态:ClosedStateOpenedStateConfiguredStatePreviewStatePreCaptureCaptureCaptureBurst。而 CameraContext 是整个项目的主要 class。所有状态都继承自 AbstractState.

ClosedOpened 状态非常简单。就几行代码,非常具体

Configured 刚开始预览。

PreviewState有capturesequence和capture single photo的功能(它调用camera2的session.capturesession.captureBurst和session.

Capturing states,顾名思义,负责拍照(capturestarted,capture completed,onimageavailable)

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

在此信息之后,是时候描述相机上下文了。您可能从维基百科了解到,它是所有调用的客户端。所以它包含了很多方法: openCamera、createSession、startPreview、captureStillPic、captureSequence。还有回调函数,onCameraOpen、onCameraClose、onImageAvailable,等等。其中一些方法只是 state-specific 方法的桥梁(CameraContext 的 onCameraOpen,是 ClosedState 的 onCameraOpen 的桥梁,等等)。

更重要的是,在Camera2Api中我们有4个不同且非常重要的回调应该实现:CameraSessionCallbackCameraStateCallbackCameraCaptureCallbackImageAvailableListener。所以我创建了 StateAware 等效的 classes,它们只是 cameraContext 调用的桥梁(onCameraOpen of StateAwareCameraStateCallback calls onCameraOpen of CameraContext,调用 [= ClosedState 的 30=],依此类推)。这些回调传递给 Camera2API 对象。

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