在移动端实现 AI 能力,ML Kit 提供了两种模式:动态下载(Google Play Services 模式)和静态捆绑(Bundled 模式)。为了确保在完全离线环境下可用,我们通常选择静态捆绑,将模型权重直接嵌入 APK。
1、 环境配置与依赖引入
首先,在 build.gradle 中引入具体的 API 库。以“通用对象检测与追踪”为例,离线版库名通常带有 -bundled 后缀或特定的版本标识。
dependencies {
// 静态捆绑模式:模型随 APK 发布,不依赖 Google Play 服务下载
implementation 'com.google.mlkit:object-detection:17.0.0'
// 若需扫描条码
implementation 'com.google.mlkit:barcode-scanning:17.2.0'
}
2、 核心集成步骤
1. 配置检测器选项 (Options)
根据业务需求配置探测模式。对于离线实时流,建议开启 TYPE_STREAM 模式并启用分类功能。
val options = ObjectDetectorOptions.Builder()
.setDetectorMode(ObjectDetectorOptions.STREAM_MODE)
.enableClassification() // 开启粗略分类
.enableMultipleObjects() // 检测多个对象
.build()
val objectDetector = ObjectDetection.getClient(options)
2. 构建输入图像 (InputImage)
ML Kit 支持多种输入源。在 AOSP 或 NDK 开发中,如果你拿到的是 byte[] 或 ByteBuffer,需注意图像旋转角度(Rotation)。
// 支持 Media Image, Bitmap, ByteBuffer 或 File
val image = InputImage.fromMediaImage(mediaImage, rotationDegrees)
3. 执行异步推理
推理过程在非 UI 线程执行。通过 Task API 监听结果。
objectDetector.process(image)
.addOnSuccessListener { detectedObjects ->
for (obj in detectedObjects) {
val bounds = obj.boundingBox
val text = obj.labels.firstOrNull()?.text ?: "Unknown"
// 处理检测到的边界框与标签
}
}
.addOnFailureListener { e ->
// 处理异常
}
3、 专家级优化建议
- 资源释放:ML Kit 的检测器持有原生内存资源。务必在 Activity 或 Fragment 的 onDestroy() 中调用 detector.close(),防止内存泄漏,这在 AOSP 系统级应用中尤为重要。
- 线程管理:虽然 process() 是异步的,但图片的预处理(如缩放、格式转换)应放在独立的 Executor 中,避免阻塞主线程。
- 模型包体积裁剪:离线集成会显著增加 APK 体积(约 5MB-30MB 不等)。建议利用 abiFilters(如 arm64-v8a)移除不必要的架构库。
- 实时流控:在处理 Camera 帧时,若推理速度赶不上帧率,应采用“丢帧机制”:当上一帧未处理完时,直接跳过当前帧,确保画面预览的流畅性。
4、 总结
离线 ML Kit 集成的逻辑清晰:引入 Bundled 依赖 -> 配置 Detector -> 封装 InputImage -> 处理 Result。对于追求极致性能的场景,可以结合 TensorFlow Lite Delegate 调用 GPU 或 NNAPI 进行硬件加速,进一步压低推理延迟。