2011-09-12 22 views
5

kullanarak bir yerel yöntemden bir Java yöntemini çağıran bir sorun var Birisi bana yardımcı olabilir umuyorum bir JNI sorun var.
Yerel bir iş parçacığından LUSOutputJNI adlı bir Java sınıfının yapıcısını çağırmaya çalışıyorum.
Bu özel sınıfın FindClass (...) dosyasında başarısız oluyor.JNI (C++)

E/lusCore_JNI(3040): 1 
E/lusCore_JNI(3040): 2 
E/lusCore_JNI(3040): AttachCurrentThread was successful 
E/lusCore_JNI(3040): 3 
E/lusCore_JNI(3040): Can't find class LUSOutputJNI 
E/lusCore_JNI(3040): 4 
W/dalvikvm(3040): JNI WARNING: JNI method called with exception raised 

Gözlemler:

  • Ben bir sonuç elde İşte
    LOGE("1"); 
        JNIEnv *env = NULL; 
    
        LOGE("2"); 
        int res = -1; 
        res = g_vm->AttachCurrentThread(&env, NULL); 
    
        if(env == NULL) 
        { 
         LOGE("env is NULL, AttachCurrentThread failed");; 
        } 
    
    
        if(res >= 0) 
         LOGE("AttachCurrentThread was successful"); 
        jclass clazz = NULL; 
        jmethodID cid; 
    
        jclass clazzESEngine; 
        jmethodID callbackid; 
    
        jobject jCoreOut; 
        static jfieldID fid_ActionState = NULL; 
        static jfieldID fid_nSpeed = NULL; 
        static jfieldID fid_nType = NULL; 
        static jfieldID fid_nInProcess = NULL; 
        static jfieldID fid_nX = NULL; 
        static jfieldID fid_nY = NULL; 
        LOGE("3"); 
    
        static const char* const ECOClassName = "lus/android/sdk/LUSOutputJNI"; 
        //static const char* const ECOClassName = "android/widget/TextView"; 
        clazz = env->FindClass(ECOClassName); 
        if (clazz == NULL) { 
         LOGE("Can't find class LUSOutputJNI"); 
    
        } 
        else 
         LOGE("lus/android/sdk/LUSOutputJNI was found, YEY!!"); 
    
        LOGE("4"); 
        cid = env->GetMethodID(clazz,"<init>", "()V"); 
        LOGE("5"); 
        jCoreOut = env->NewObject(clazz, cid); 
    
        LOGE("6");  
    

    başarısız olduğunda gelen logcat çıkışı: Burada

    kodudur AttachCurrentThread olan 0, whic h bu ekin başarılı olduğunu, +v işaretçisinin artık NULL olmadığını gösterir.
  • LUSOutputJNI paket adı bildirimi hakkında eminim (üçlü kontrol ettiniz ...)
  • Android/widget/TextView gibi daha popüler bir sınıf adıyla FindClass (..) çalıştırmayı denediğimde, I olumlu bir eşleşme olsun. O orada. İş parçacığı eki ve env değişkenleri anlamlıdır. (Bunu varsayabilir miyim?)
  • Bir JNI iş parçacığı çalıştıran bir JNI yönteminden aşağıdaki kodu çalıştırmayı denediğimde, LUSOutputJNI sınıfını sorun olmadan bulur.

Neyi yanlış yapıyorum?

Yardım çok yanlış ne oluyor (o, LOGE değil stderr oturum olacak hakkında biraz daha bilgi almak için Ita

+0

Bu 'LUSOutputJNI' sınıfına atıfta bulunuluyor mu? –

+0

@ K-ballo: Muhtemelen bir kurum içi sınıftır. –

+0

@Ita: LUSOutputJNI statik başlatıcınız bir istisna atar mı? Yükseltilen istisnayı yazdırmalısınız. –

cevap

6

Cevabı burada bulabilirsiniz. (SSS için bakın: "FindClass benim sınıfımı bulamadı" JNI tips)

Temel teknikler, gerekli jclass nesnelerine bir global ref kaydettim. Bununla birlikte, kodun derlenmesi için C/JNI ve C++/JNI arasındaki bazı kötü JNI değişikliklerinin üstesinden gelmek zorunda kalmıştır.
Bu şekilde derlemek ve çalışmak için NewGlobalRef'i aldım.

jclass localRefCls = env->FindClass(strLUSClassName); 
if (localRefCls == NULL) { 
    LOGE("Can't find class %s",strLUSCoreClassName); 
    return result; 
} 

//cache the EyeSightCore ref as global 
/* Create a global reference */ 
clazzLUSCore = (_jclass*)env->NewGlobalRef(localRefCls); 

/* The local reference is no longer useful */ 
env->DeleteLocalRef(localRefCls); 

/* Is the global reference created successfully? */ 
if (clazzLUSCore == NULL) { 
    LOGE("Error - clazzLUSCore is still null when it is suppose to be global"); 
    return result; /* out of memory exception thrown */ 
} 

Umarım bu, herkese yardımcı olur.

+0

Teşekkürler, bu yardımcı oldu. Burada yerel ref silmek gerçekten gerekli mi? Fonksiyon döndüğünde otomatik olarak silinir inanıyorum: http://android-developers.blogspot.co.il/2011/11/jni-local-reference-changes-in-ics.html – snowdragon

2

:) zaman için

Teşekkür,

takdir edilecek ve biraz istisna baskı ekleyebilirsiniz) o nasıl değiştirileceği emin değilim - bunu değiştirebilirsiniz: Buna

//static const char* const ECOClassName = "android/widget/TextView"; 
clazz = env->FindClass(ECOClassName); 
if (clazz == NULL) { 
    LOGE("Can't find class LUSOutputJNI"); 

} 
else 
    LOGE("lus/android/sdk/LUSOutputJNI was found, YEY!!"); 

:

//static const char* const ECOClassName = "android/widget/TextView"; 
    clazz = env->FindClass(ECOClassName); 
    if (clazz == NULL) { 
     LOGE("Can't find class LUSOutputJNI"); 
     jthrowable exc = env->ExceptionOccurred(); 
     if(exc) 
     { 
      env->ExceptionDescribe(); 
      env->ExceptionClear(); 
     }  
    } 
    else 
     LOGE("lus/android/sdk/LUSOutputJNI was found, YEY!!"); 
+1

Jthrowable içindeki toString işlevini kullanarak hata bilgisini alabilirsiniz ve bunu bir C dizesine dönüştürün ve bunu LOG ​​işlevine dönüştürün, ancak bunu hata ayıklamak için aşırı sıkıcı olabilir. –