【问题标题】:Writing data in native heap to disk in Android在Android中将本机堆中的数据写入磁盘
【发布时间】:2020-07-03 17:15:15
【问题描述】:

我正在用原生代码对 RGB 数据进行 JPEG 编码,最终的 JPEG 编码数据在原生字节数组中可用。将这些数据写入磁盘的有效方法是什么?无需对此输出进行更多处理。

我能想到的一些选项是:

  • 在 Java Native 边界之间复制数据并使用标准 Android 方法将数据写入磁盘。
  • 以本机代码本身将数据写入磁盘。但随着 Android Q 转向范围存储访问,我一直在通过 MediaStore 写入数据。我们可以从原生代码写入 MediaStore 吗?
  • 在 Java 代码中分配一个 ByteBuffer,将其传递给本机代码进行写入,然后一旦编码结束,将 ByteBuffer 中的数据刷新到磁盘。这看起来很公平,但我更喜欢在原生层进行内存管理,而不是依赖于 java 层中的 GC。

我强烈感觉我的一些假设是错误的,请指出它们以供我学习。

【问题讨论】:

标签: android memory java-native-interface


【解决方案1】:

如果文件仅供您的应用程序使用,您可以只写入您的应用程序缓存 (getExternalCacheDir) 或数据 (getExternalFilesDir) 目录。

如果您想让其他文件可以访问它们,您可以按照您的提示使用 MediaStore 框架。您可以将官方文档中的this example修改为以下内容:

val resolver = applicationContext.contentResolver

val imagesCollection = MediaStore.Images.Media
        .getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)

val imageDetails = ContentValues().apply {
    put(MediaStore.Images.Media.DISPLAY_NAME, "fancy_image.jpg")
    put(MediaStore.Images.Media.IS_PENDING, 1)
}

val imageContentUri = resolver.insert(imagesCollection, imageDetails)

resolver.openFileDescriptor(imageContentUri, "w", null).use { pfd ->
    int fd = pfd.getFd
    // this would be your native implementation. it should `write()` to the fd or 
    // call `fdopen` and then `fwrite`. The `use` block will automatically call 
    // `close` for you.
    native_writeFile(fd)
}

// Now that we're finished, release the "pending" status, and allow other apps
// to see the image
imageDetails.clear()
imageDetails.put(MediaStore.Images.Media.IS_PENDING, 0)
resolver.update(imageContentUri, imageDetails, null, null)

【讨论】:

    猜你喜欢
    • 2019-01-09
    • 2017-10-12
    • 2011-10-21
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    相关资源
    最近更新 更多