2011-11-28 93 views
2

我使用這個方法來加載資產NDK: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?也許這只是我的設備內存不足的問題?

回答

-1

我不知道你的具體問題,但我可以提供一個替代的解決方案,以打開資產JNI方:

  1. Java端創建每個所討論的文件AssetFileDescriptor(稱之爲FD現在上
  2. 傳遞fd.getFileDescriptor(),fd.getStartOffset()的值,並fd.getLength()的JNI函數
  3. JNI方面,你現在可以使用fdopen(),FSEEK(),FREAD()等使用#2的信息
  4. 不要忘了在你的JNI工作後調用fd.close()

希望幫助

+0

而如果我使用NDK中的一個庫,需要一個文件路徑。例如,sqlite open()函數獲取數據庫文件的路徑。這種情況下最好的解決方案是什麼? – Damian

+0

如果您需要路徑,只需使用路徑即可。在你使用sqlite_open()的例子中,你很可能會想要使用getExternalStorageDirectory()構建Java端的東西,然後通過JNI傳遞並最終傳遞給SQLite。 – NuSkooler

+0

不,我的意思是,如何打開包含在apk中的資源的sqlite數據庫。 – Damian