关于 camerax
为 Android 开发者提供 CameraX 相机应用的实践指导,涵盖 Camera2Interop 和 Media3 集成。内容还包括旧相机 API 迁移、复杂功能规划、现代 API 选择及跨设备测试建议。
主要功能
- 01Camera1 和 Camera2 迁移指导
- 02CameraX 不可变 API 使用模式
- 03手动控制、RAW 与低光功能规划
- 04Media3 效果与分析 API 建议
- 05设备适配、生命周期与测试规范
适用场景
- 01将旧相机应用迁移到 CameraX
- 02实现 RAW 拍摄或手动相机控制
- 03处理折叠屏及多摄像头设备
- 04测试相机分析与异步生命周期
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ android/ skills --skill camerax安装后在 Claude Code 中输入/camerax确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/camera1-to-camerax.mdcamera2-to-camerax.mdexpert-blueprints.mdfoldables.mdimmutability.mdlow-light.mdmlkit-spatial.mdmodern-apis.mdtesting.mdthermals.mdwear-os.mdxr.md详细介绍
此技能提供了在 Android 上构建相机应用的流程指导和标准模式,重点介绍 CameraX,包括其
Camera2Interop 实用工具,以及 Media3 集成。
核心工作流
处理不可变 API 模式
各种 Android 相机和媒体 API,尤其是 CameraX VideoCapture,都采用流畅、不可变的构建器式模式,其中方法会返回一个新实例。
如果不重新赋值,这些结果就会被忽略,导致音频等设置不生效。
模式:必须重新赋值
// WRONG
run {
val pending = recorder.prepareRecording(context, opts)
pending.withAudioEnabled() // This returns a new instance which is ignored
val active = pending.start(exec, listener)
}
// CORRECT
run {
val pending = recorder.prepareRecording(context, opts)
.withAudioEnabled() // Chaining works
val active = pending.start(exec, listener)
}
// ALSO CORRECT
run {
var pending = recorder.prepareRecording(context, opts)
pending = pending.withAudioEnabled() // Reassignment
val active = pending.start(exec, listener)
}
请参阅不可变性,了解受影响的类列表。
迁移到 CameraX
将旧版相机代码库迁移到 CameraX Jetpack 库时:
- Camera1 迁移到 CameraX:如需迁移旧版
android.hardware.Camera实现、表面处理和手动生命周期,请参阅 Camera1 迁移指南。 - Camera2 迁移到 CameraX:如需迁移较新但冗长的
android.hardware.camera2实现、会话状态回调和互操作模式,请参阅 Camera2 迁移指南。
全面的功能蓝图设计
对于涉及多个文件和硬件级连接的多步骤功能,请遵循结构化蓝图设计方法,以避免系统超时。此类复杂功能包括:
- 手动控制:拆分为
ViewModel状态、控制器层和会话中的Camera2Interop连接。 - RAW 拍摄:将 JPEG 和 RAW 输出配置拆分为独立的构建步骤。
- 自定义效果:除非绝对需要更高性能,否则优先使用
Media3Effect或SurfaceProcessor,而不是手动搭建 OpenGL 管线。 - 弱光:请参阅弱光,了解夜间模式和 LLB 指南。
- 折叠设备:请参阅折叠设备,了解如何处理动态姿态和铰链状态。
- XR、AR 和 VR:请参阅 xr,了解空间跟踪、透视同步和延迟防护措施。
- 热管理和电源:请参阅热管理,了解如何管理
StreamUseCase优化和PowerManager热状态。 - 测试与模拟:请参阅测试,了解如何使用
FakeCameraConfig、处理异步生命周期以及验证分析管线。 - ML Kit 空间分析:请参阅 mlkit-spatial,了解坐标映射、旋转逻辑和镜像镜头处理。
- Wear OS 相机远程控制:请参阅 wear-os,了解圆形 UI 限制、Data Layer API 同步和远程触发逻辑。
请参阅 expert-blueprints,了解分步指南。
API 探索
始终使用更高层级的抽象,而不是底层手动连接:
- 分析:使用
MlKitAnalyzer,而不是手动实现ImageAnalysis.Analyzer。 - 滤镜和效果:使用
Media3Effect进行标准后期处理。 - 多摄像头:使用
ConcurrentCameraAPI 设置双流。
请参阅 modern-apis,了解当前建议。
代码质量和架构规范
构建相机实现时,请遵循以下 Android 生态系统标准模式:
- 测试中优先使用 Fake,而非 Mock:避免使用
Mockito等 Mock 库,尤其是在处理ImageProxy这类涉及多步操作的 CameraX 接口时。构建“Fake”以验证状态,而不是验证不可靠的实现细节。 - 使用 Google Truth 断言:优先使用
assertThat,而不是assertEquals等标准JUnit断言,以提升可读性。 - 显式指定测试运行器:始终为测试类定义显式的
@RunWith,确保 CI 环境能够正确执行测试。 - 语义化 UI 合并:在 Compose 中构建自定义相机控件时,例如包含
Icon和Text的按钮,请使用semantics { mergeDescendants = true },确保屏幕阅读器将其作为一个连贯的整体进行播报。
硬件和设备多样性
相机应用运行于各种硬件上,从手机和折叠屏设备到平板电脑、笔记本电脑,甚至智能家电。请考虑应用运行所用硬件的具体情况。
- 设备形态:考虑折叠屏设备和平板电脑的屏幕尺寸及方向变化。
- 多摄像头阵列:有些设备配有前置摄像头和后置摄像头;另一些设备则配有多个后置摄像头,例如广角镜头和长焦镜头。
- 功能一致性:闪光灯或自动对焦等功能在不同硬件上的表现有所不同。例如,CameraX 同时支持物理闪光灯、后置摄像头,以及基于屏幕的闪光灯和前置摄像头;实现闪光灯功能时必须将这些情况都考虑在内。
常见问题
- 异步生命周期:尝试停止或暂停前,请检查
isRecording状态。处理VideoRecordEvent.Start以更新 UI 状态,而不只是处理初始调用。 - 线程安全:相机回调通常在后台执行器上运行。请在主线程上分发 UI 更新。
- 权限处理:检查
CAMERA权限;在VideoCapture中启用音频时,务必检查RECORD_AUDIO权限。
评论
支持 Markdown