【问题标题】:NDK load assetsNDK 加载资产
【发布时间】:2011-11-28 10:21:16
【问题描述】:

我正在使用这种方法在 NDK 中加载资产:

jclass localRefCls = myEnv->FindClass("(...)/AssetLoaderHelper");
helperClass = reinterpret_cast<jclass>(myEnv->NewGlobalRef(localRefCls));
myEnv->DeleteLocalRef(localRefCls);

helperMethod1ID = myEnv->GetStaticMethodID(helperClass, "getFileData", "(Ljava/lang/String;)[B");

...

myEnv->PushLocalFrame(10);

jstring pathString = myEnv->NewStringUTF(path);
jbyteArray data = (jbyteArray) myEnv->CallStaticObjectMethod(helperClass, helperMethod1ID, pathString);

char* buffer = new char[len];
myEnv->GetByteArrayRegion(data, 0, len, (jbyte*)buffer);

myEnv->DeleteLocalRef(pathString);
myEnv->DeleteLocalRef(data);

jobject result;
myEnv->PopLocalFrame(result);
myEnv->DeleteLocalRef(result);

return buffer;

在java中:

public static byte[] getFileData(String path)
{
InputStream asset = getAsset(path); //my method using InputStream.open

byte[] b = null;
try
{
    int size = asset.available();
    b = new byte[size];
    asset.read(b, 0, size);
    asset.close();
}
catch (IOException e1)
{
    Log.e("getFileData", e1.getMessage());
}

return b;
}

它可以工作,但是当我加载许多资产时,会出现崩溃或系统锁定。我是否犯了任何错误或有人知道将资产加载到 NDK 的更好方法?也许这只是我设备内存不足的问题?

【问题讨论】:

    标签: android android-ndk


    【解决方案1】:

    我不确定您的确切问题,但我可能会提供另一种解决方案来打开资产 JNI 端:

    1. Java 端为每个有问题的文件创建一个 AssetFileDescriptor(现在调用这个 fd
    2. 将 fd.getFileDescriptor()、fd.getStartOffset() 和 fd.getLength() 的值传递给 JNI 函数
    3. JNI 方面,您现在可以使用来自 #2 的信息来使用 fdopen()、fseek()、fread() 等
    4. 不要忘记在 JNI 工作后调用 fd.close()

    希望有帮助

    【讨论】:

    • 如果我在 ndk 中使用需要文件路径的库怎么办。例如 sqlite open() 函数获取数据库文件的路径。在这种情况下,最好的解决方案是什么?
    • 如果需要路径,直接使用路径即可。在您使用 sqlite_open() 的示例中,您很可能希望使用 getExternalStorageDirectory() 在 Java 端构建一些东西,然后通过 JNI 传递并最终传递给 SQLite。
    • 不,我的意思是,如何打开作为 apk 资源包含的 sqlite 数据库。
    • 那你需要按照我的回答中描述的去做。
    猜你喜欢
    • 2020-07-06
    • 2021-09-19
    • 2017-06-06
    • 2016-12-16
    • 2017-07-17
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多