Android资产,C,JNI

时间:2011-01-24 08:26:50

标签: android c java-native-interface assets

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

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

2 个答案:

答案 0 :(得分:11)

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

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

所以我看到三个选项:

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

答案 1 :(得分:2)

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

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

将文件放在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;
}