Cómo llamar a Java API de subproceso de C ++ de NDK?
Quiero llamar a Java API de NDK C + + hilo, pero env-> FindClass () devolver 0. Pero cuando llamo API de Java en el hilo principal, funciona bien. Ya he llamado AttachCurrentThread () en el hilo, ¿puede alguien ayudarme?
Aquí está el código fuente:
- NewGlobalRef para jmethodID
- No se encontró JNI_OnLoad saltando init> Apagado de la aplicación
- Integración de Unity3d con android
- Rendimiento de Android NDK sobre el código Java habitual
- Comprimir vídeos utilizando FFMPEG y JNI
CÓDIGO JAVA:
public class simple_test extends Activity { ... // This functin will be called in C++ public void PrintNdkLog(String slog) { Log.e(logTagNDK, slog); return; } }
CÓDIGO C ++:
static JavaVM* g_JavaVM = NULL; jobject getInstance(JNIEnv *env, jclass obj_class) { jmethodID c_id = env->GetMethodID(obj_class, "<init>", "()V"); jobject obj = env->NewObject(obj_class, c_id); return obj; } // JNI OnLoad JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { g_JavaVM = jvm; return JNI_VERSION_1_6; } // Call JAVA API "PrintNdkLog" in this function void PrintNdkLog(char *lpLog) { if (g_JavaVM == NULL) return; JNIEnv *env = NULL; g_JavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); if (env == NULL) return; jclass cls = env->FindClass("com/myndk/simple_test"); if (cls != 0) // **cls will be 0 when PrintNdkLog() is called in thread** { LOGE("FindClass error %p", cls); } else { jmethodID mid; jobject obj; obj = getInstance(env, cls); mid = env->GetMethodID(cls, "PrintNdkLog", "(Ljava/lang/String;)V"); if (mid != 0) { jstring jstrMSG = env->NewStringUTF(lpLog); env->CallVoidMethod(obj, mid, jstrMSG); } } } // Call JAVA API in thread static void* thread_test(void* ptr) { JNIEnv *envLocal; int status = g_JavaVM->GetEnv((void **) &envLocal, JNI_VERSION_1_6); if (status == JNI_EDETACHED) { status = g_JavaVM->AttachCurrentThread(&envLocal, NULL); if (status != JNI_OK) LOGE("AttachCurrentThread failed %d",status); } PrintNdkLog("bbb"); // This JAVA callback failed, and printed "FindClass error" } // Create thread int NdkThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam, int nPriority) { PrintNdkLog("aaa"); // This JAVA callback runs well pthread_t pid; pthread_create(&pid, NULL, thread_test, pParam); }
- ¿Cómo crear un objeto con JNI?
- Android NDK, ninguna regla para hacer objetivo
- Obtener un ANativeWindowBuffer de ANativeWindow_Buffer
- ¿Cómo funciona NDK en Android - ¿Cuál es la orden que NDK, JNI etc se utilizan?
- Recortar video como whatsapp
- Android NDK Exception failed: dlopen failed: no se puede localizar el símbolo "_ZN7Tangram11setPositionEdd" referenciado por "libtangram.so"
- Cómo utilizar c / cpp biblioteca / funciones en android
- Javah: Error: no se puede acceder a android.support.v7.app.ActionBarActivity
Lo he resuelto ahora. En el subproceso nativo de NDK, sólo se puede llamar a la API de Java estática. Si llama a env-> FindClass (), desencadenaría una excepción. http://android.wooyd.org/JNIExample dio la información de detalle.
Sugiere echar un vistazo a AttachCurrentThread .
Aquí hay un ejemplo de código para hacer eso:
// Global variable JavaVM *g_jvm = NULL; //Get g_jvm from jni main thread use env->GetJavaVM(&g_jvm); jobject g_obj = NULL; //Where the java function exist. (some activity) //Get env in thread function and attach the env JNIEnv *env; if(g_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) { LOGD("%s: AttachCurrentThread() failed", __FUNCTION__); } const char * fnName ="somFunctionInYourJava"; //which should be "pulic void somFunctionInYourJava(String input);" jstring retStr = env->NewStringUTF(str); jclass cls = env->GetObjectClass(thiz); jmethodID messageMe = env->GetMethodID(cls, fnName, "(Ljava/lang/String;)V"); env->CallVoidMethod(thiz, messageMe, retStr); //Detach thread and release related resource if(g_jvm->DetachCurrentThread() != JNI_OK) { LOGD("%s: DetachCurrentThread() failed", __FUNCTION__); }
- Creación de imágenes personalizadas
- Error de configuración de Sandbox en la aplicación de Android en un ID de Gmail concreto