2014-10-23 21 views
12

Ben JNI şeyler hakkında okuyordum ve bir iş parçacığı başlarsa ne olacağını anlayamıyorum görünüyor -> çağrılar AttachCurrentThread() -> bazı JNI aramaları yapmak -> iş parçacığı çıkışı.Android JNI - Call AttachCurrentThread olmadan DetachCurrentThread

İdeal olarak, iş parçacığı çıkmadan önce DetachCurrentThread() yöntemini çağırmalıyız, ancak uygulama bunu yapmıyorsa bunun sonuçları nelerdir? Bellek sızıntısına veya başka bir soruna neden olur mu?

+0

dikkat edin, eğer sadece gerektiği İş parçacığını eklediyseniz, DetachCurrentThread() işlevini çağırın. JVM'ye ait bir iş parçacığı tanımlanmamışsa, geçerli iş parçacığı ayırma davranışı tanımlanmamış. – technomage

cevap

20

DetachCurrentThread() numaralı telefonu aramanız kesinlikle bir bellek sızıntısına neden olacaktır; Diğer sonuçlar JVM'ye özgüdür ve muhtemelen Android uygulamaları için ilgisizdir, JVM, işlem'dan çıktığında kapanır. http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier

Güncelleme: iplik,/Ayrıl takın örneğin bkz yönetmek için yardımcı epeyce C++ sayida sayfa vardir 1000 sayesinde göz açıklığına link için fadden için; Dalvik'te, DetachCurrentThread() numaralı telefonu aramadan çıkan bir iş parçacığı, tüm VM'yi ve işlemin çökmesini sağlar. İşte

10-26 04:16:25.853: D/dalvikvm(1554): Trying to load lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 
10-26 04:16:25.893: D/dalvikvm(1554): Added shared lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 
10-26 04:16:25.893: D/dalvikvm(1554): No JNI_OnLoad found in /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0, skipping init 
10-26 04:16:26.463: D/gralloc_goldfish(1554): Emulator without GPU emulation detected. 
10-26 04:16:31.033: D/threadFunction(1554): Attaching 
10-26 04:16:31.173: D/threadFunction(1554): Not Detaching 
10-26 04:16:31.183: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=0) 
10-26 04:16:31.193: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=1) 
10-26 04:16:31.193: E/dalvikvm(1554): threadid=11: native thread exited without detaching 
10-26 04:16:31.193: E/dalvikvm(1554): VM aborting 
10-26 04:16:31.213: A/libc(1554): Fatal signal 6 (SIGABRT) at 0x00000612 (code=-6), thread 1567 (xample.hellojni) 

hello-jni.c eklenen alakalı fonksiyonudur: Burada

, NDK dan HelloJni örnekleme dayalı kodum resmi emülatörü gelen logcat olan

static JavaVM* jvm = 0; 
static jobject activity = 0; // GlobalRef 

void* threadFunction(void* irrelevant) 
{ 
    JNIEnv* env; 
    usleep(5000000); 

    __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Attaching"); 

    (*jvm)->AttachCurrentThread(jvm, &env, NULL); 

    jclass clazz = (*env)->GetObjectClass(env, activity); 
    jmethodID methodID = (*env)->GetMethodID(env, clazz, "finish", "()V"); 
    (*env)->CallVoidMethod(env, activity, methodID); 

    __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Not Detaching"); 
// (*jvm)->DetachCurrentThread(jvm); 
} 

jstring 
Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv* env, 
                jobject thiz) 
{ 
    (*env)->GetJavaVM(env, &jvm); 
    activity = (*env)->NewGlobalRef(env, thiz); 

    pthread_t hThread; 
    pthread_create(&hThread, NULL, &threadFunction, NULL); 
    return (*env)->NewStringUTF(env, "Hello from JNI !"); 
} 
+0

Bağlantıya erişemiyorum. – pree

+0

Ayrıca, çok sayıda iş parçacığı oluşturduğum ve ayrılmadan attachcurrentthread öğesini çağırırsam, bellek sızıntısı olabilir. Ancak, birkaç uzun çalışan iş parçacığı varsa ve detachcurrentthread çağırmadan çıkılırsa ne olur? Bu etki ne olurdu? Çıktıktan sonra kendini otomatik olarak ayırmaz mı? – pree

+0

Hayır, iş parçacığı süreç ("Android'de her ikisi de aynı anda gerçekleşir) kapanana kadar" kendilerini otomatik olarak ayırmaz ". Daha önce de belirttiğim gibi, JVM'nin bir süreci ya da tersini yapabileceği diğer platformlarda, bu etki daha acı verici olabilir. Ayrıca, sızıntı çok önemli olabilir, bu, belirli iş parçacığının JNI'sini nasıl ele aldığına bağlıdır. –