Android 离线 ML Kit 高效集成方案

5 阅读2分钟

在移动端实现 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、 专家级优化建议

  1. 资源释放:ML Kit 的检测器持有原生内存资源。务必在 Activity 或 Fragment 的 onDestroy() 中调用 detector.close(),防止内存泄漏,这在 AOSP 系统级应用中尤为重要。
  2. 线程管理:虽然 process() 是异步的,但图片的预处理(如缩放、格式转换)应放在独立的 Executor 中,避免阻塞主线程。
  3. 模型包体积裁剪:离线集成会显著增加 APK 体积(约 5MB-30MB 不等)。建议利用 abiFilters(如 arm64-v8a)移除不必要的架构库。
  4. 实时流控:在处理 Camera 帧时,若推理速度赶不上帧率,应采用“丢帧机制”:当上一帧未处理完时,直接跳过当前帧,确保画面预览的流畅性。

4、 总结

离线 ML Kit 集成的逻辑清晰:引入 Bundled 依赖 -> 配置 Detector -> 封装 InputImage -> 处理 Result。对于追求极致性能的场景,可以结合 TensorFlow Lite Delegate 调用 GPU 或 NNAPI 进行硬件加速,进一步压低推理延迟。