【问题标题】:Android assets, C, JNIAndroid 资产、C、JNI
【发布时间】:2011-01-24 08:26:49
【问题描述】:

如何使用 JNI 从 C 访问 Android 资产,例如 .txt 文件?

我正在尝试“file:///android_asset/myFile.txt”,并在本地尝试“myFile.txt”,并在 jni 文件夹中使用 C 实现文件复制 myFile.txt。

【问题讨论】:

标签: android c java-native-interface assets


【解决方案1】:

资产的问题是您不能直接将它们作为文件访问。这是因为资产是直接从 APK 中读取的。它们不会在安装时解压缩到给定的文件夹中。

从 Android 2.3 开始,有一个用于访问资产的 C API。查看<android/asset_manager.h><android/native_activity.h> 中的assetManager 字段。不过我从来没有使用过这个,如果你不依赖原生活动,我不确定你是否可以使用这个资产管理器 API。无论如何,这不适用于 Android 2.2 及更低版本。

所以我看到了三个选项:

  • 您可以将资产提取到某个目录中,但这会占用额外空间
  • 您可以(捆绑并)使用 libzip 之类的东西以纯 C 语言从 APK 中读取资产。
  • 或者,为了避免捆绑额外的库,我个人的偏好是使用 JNI 从 AssetManager.open() 返回的 Java InputStream 对象中读取 C 中的数据。它需要一些代码,但效果很好。

【讨论】:

  • @olivierg 有一个关于如何使用 JNI 来使用 AssetManager 中的 Inputstream 的示例吗?
【解决方案2】:

如果您无法使用 AssetManager C API,因为您需要调用需要文件名的 C/C++ 库,则可以使用原始资源。

唯一的缺点是它需要在运行时复制到应用程序的数据 (temp) 目录中。

将文件放在 res/raw 中

将要从本机代码读取的文件放在res/raw 目录中。

制作副本

在运行时,将文件从res/raw/myfile.xml 复制到data 目录:

File dstDir = getDir("data", Context.MODE_PRIVATE);
File myFile = new File(dstDir, "tmp_myfile.xml");
FileMgr.copyResource(getResources(), R.raw.my_file, myFile);

现在传递给本机代码的文件名是myFile.getAbsolutePath()

copyResource (rsrcId, dstFile)

public static File copyResource (Resources r, int rsrcId, File dstFile) throws IOException
{
    // load cascade file from application resources
    InputStream is =  r.openRawResource(rsrcId);
    FileOutputStream os = new FileOutputStream(dstFile);

    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1)
        os.write(buffer, 0, bytesRead);
    is.close();
    os.close();

    return dstFile;
}

【讨论】:

  • 很抱歉让这个帖子在很长一段时间后重新上线。我从asset 文件夹中读取了一个文件,然后使用FileOutputStream 编写了该文件。我的问题是FileOutputStream保存的文件路径是什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 2014-06-26
  • 2017-09-09
  • 1970-01-01
相关资源
最近更新 更多