2014-12-22 14 views
0

這裏是我的程序:如何解決env-> NewObject()上的JNI崩潰?

extern "C" {   
JNIEXPORT jint Java_android_app_integrity_VerifyIntegrity_checkCrc(JNIEnv *jniEnv,jobject thiz,jstring crcStr) { 

    jclass clsZipFile = jniEnv->FindClass("java/util/zip/ZipFile"); 
    jmethodID mtdConstruct = jniEnv->GetMethodID(clsZipFile, "<init>", "(Ljava/lang/String;)V"); 
    jmethodID mtdGetEntry = jniEnv->GetMethodID(clsZipFile,"getEntry","(Ljava/lang/String;)Ljava/util/zip/ZipEntry;"); 
    jclass clsZipEntry = jniEnv->FindClass("java/util/zip/ZipEntry"); 
    jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()L"); 
    LOGD("pos2"); 

    jobject objZipFile = jniEnv->NewObject(clsZipFile,mtdConstruct,crcStr); 
    if (NULL == objZipFile){ 
     LOGD("NULL == objZipFile"); 
    } 

    LOGD("pos3"); 
    jobject objZipEntry = jniEnv->CallObjectMethod(objZipFile, mtdGetEntry,"classes.dex"); 
    LOGD("pos4"); 
    jlong ret = jniEnv->CallLongMethod(objZipEntry, mtdGetCrc); 

    LOGD("%ld",(long int)ret); 
    return 0; 
} 
}; 

它僅打印 「POS2」。 「LOGD(」pos2「);」會導致崩潰! 我找不到原因。誰能幫我?謝謝!

+1

只是好奇 - 你爲什麼要這樣做?您將一個Java字符串傳遞給C,然後僅使用它來創建一個Java對象 - 只需在java端執行該操作,並傳遞給jobject以避免一些JNI的痛苦。事實上,在C中完成這些任何事都沒有什麼好的理由。你甚至不會得到速度提升。 –

+1

您需要更多的錯誤檢查。 *您調用的每個* JNI API都可能以靜默方式失敗。顯然,類查找或構造函數查找失敗。你爲什麼在JNI中編寫這個代碼呢?這是一行Java代碼。 – EJP

回答

0

嘗試修復以下行。它有一個無效的簽名,並且會引發MethodNotFound異常的隱式異常,並且可能是罪魁禍首。

jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()L"); 

應該是:

jmethodID mtdGetCrc = jniEnv->GetMethodID(clsZipEntry,"getCrc","()J"); 

但是我想第二個其他建議從所有的findClass和FindMethod檢查返回值調用因爲它們不僅返回NULL,他們也各自發生故障時拋出異常。當JNI無法分配本地引用對象以返回您的jclass查找時,也會引發OutOfMemoryException。