2. Camera2与CameraX架构选型
在Android相机开发中,Camera2与CameraX并非简单的“新旧替代”关系,而是两套面向不同抽象层级的API体系。Camera2是Android 5.0引入的底层框架,直接暴露相机设备、会话、请求和图像流;CameraX则是Jetpack组件,建立在Camera2之上,用UseCase模型封装了预览、拍照、分析等常见场景。选型的本质,是判断项目需要在“控制力”和“开发效率与兼容性”之间偏向哪一端。
一、API抽象层级的根本差异
Camera2的核心对象是CameraManager、CameraDevice、CameraCaptureSession和CaptureRequest。开发者需要自己管理设备打开、会话创建、请求模板、目标Surface以及每一帧的参数。一个典型的预览加拍照流程,至少涉及设备状态回调、会话配置、两个以上Surface的绑定,以及CaptureRequest.Builder的反复构建。它的优势在于可以精确控制曝光、对焦、帧率、输出格式和硬件级别特性,例如CONTROL_AE_MODE、CONTROL_AF_MODE、SENSOR_SENSITIVITY等。
CameraX则把上述过程收敛为ProcessCameraProvider、Preview、ImageCapture、ImageAnalysis和VideoCapture等UseCase。开发者通过bindToLifecycle()把UseCase与LifecycleOwner绑定,由框架负责会话协商、分辨率选择和生命周期联动。CameraX并不屏蔽Camera2,而是通过Camera2Interop.Extender在需要时注入底层参数,形成“高层默认、低层可插”的混合模式。
二、生命周期管理的不同哲学
Camera2的生命周期完全由开发者掌控。打开相机需要调用CameraManager.openCamera(),并在CameraDevice.StateCallback中等待onOpened;关闭时必须显式调用close(),否则会持续占用相机资源,导致其他应用无法使用。会话创建、请求下发、Surface释放都需要手动配对。这种模式在复杂场景下灵活,但容易因遗漏回调或异常路径导致资源泄漏。
CameraX把生命周期绑定作为一等公民。bindToLifecycle(lifecycleOwner, useCases...)会自动在ON_START时打开相机、ON_STOP时释放,并在配置变化时重建会话。对于多UseCase组合,CameraX内部会做分辨率与格式的协商,例如Preview与ImageAnalysis同时绑定时,框架会选择两者都支持的尺寸。开发者只需关注UseCase本身的配置,而不必处理CameraCaptureSession的创建与销毁时序。
需要强调的是,CameraX的自动生命周期并非“无需理解生命周期”。当应用进入后台、分屏、画中画或折叠屏形态切换时,UseCase的绑定关系仍可能被重建。若在ImageAnalysis.Analyzer中持有大对象或阻塞线程,重建时可能引发卡顿。因此,CameraX项目同样需要关注LifecycleOwner的选择和Analyzer的线程策略。
三、适用场景与选型判断
CameraX适合以下场景:以预览、拍照、扫码、人脸检测、简单录像为主的应用;需要快速覆盖多厂商设备并减少兼容性适配;团队希望把精力放在业务逻辑而非相机状态机;对帧级参数控制要求不高,或仅需通过Interop做少量参数注入。典型如社交类拍照、文档扫描、直播推流中的预览采集。
Camera2更适合:需要精确控制3A(自动曝光、自动对焦、自动白平衡)策略;需要多路流同时输出且对分辨率、格式有严格要求;需要RAW采集、手动对焦、长曝光、高帧率慢动作;需要与Camera HAL或厂商扩展深度交互;以及需要实现自定义相机管线或专业影像处理。典型如专业相机应用、工业检测、AR底层采集、多摄协同。
实际生产中,二者并非互斥。常见做法是:用CameraX承载预览和基础拍照,用Camera2Interop注入特定参数;或在CameraX无法满足某路流需求时,单独用Camera2打开第二路设备。选型时应先列出必须满足的硬性能力,再评估CameraX能否覆盖,最后决定是否下沉到Camera2。
四、生产项目决策方法
建议用一张能力矩阵来驱动决策,而不是凭经验拍板。矩阵的维度包括:目标设备范围、必须的相机能力、团队对Camera2的熟悉度、交付周期、后续维护成本。具体可按以下顺序推进:
- 列出硬性能力清单。例如“必须支持1080p预览+1080p分析+4K拍照同时进行”“必须支持手动ISO”“必须支持RAW”。逐项标注是否可由CameraX直接实现、是否可通过Interop实现、是否必须Camera2。
- 评估设备覆盖。CameraX对Camera2的兼容层已经处理了大量厂商差异,若目标设备跨度大且团队没有充足的多机型测试资源,优先CameraX。
- 评估生命周期复杂度。若页面切换频繁、存在分屏/画中画/折叠屏,CameraX的自动绑定能显著降低状态机复杂度;若需要自定义会话复用或跨页面共享相机,Camera2更可控。
- 评估性能与延迟。CameraX的默认会话配置可能引入额外拷贝或格式转换。若对延迟敏感,应实测CameraX与Camera2在目标机型上的端到端延迟,再决定是否下沉。
- 保留演进路径。即使初期选择CameraX,也应在架构上预留
Camera2Interop入口和UseCase替换点,避免后期因一个参数无法配置而整体重写。
ImageAnalysis的setOutputImageFormat(OUTPUT_IMAGE_FORMAT_RGBA_8888)可避免YUV到RGB的额外转换,但会略增内存带宽;setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST)可防止分析帧堆积。这些配置在Camera2中需要手动管理队列,在CameraX中则通过UseCase参数直接表达。
CameraCharacteristics中的REQUEST_AVAILABLE_CAPABILITIES和SCALER_STREAM_CONFIGURATION_MAP。
总结来看,Camera2与CameraX的选型不是技术优劣之争,而是抽象层级与项目约束的匹配问题。CameraX用约定换效率,Camera2用控制换灵活。生产项目应先用能力矩阵明确边界,再以“CameraX优先、Camera2兜底、Interop补位”的策略落地,并在架构上保留切换空间,从而在交付速度与长期可维护性之间取得平衡。