android android-activity jni cocos2d-x non-static

¿Cómo hacer una llamada correcta desde Android a una función no estática en Java?(Cocos2Dx en la mezcla)



android-activity jni (1)

Así que estoy desarrollando un pequeño proyecto con Cocos2Dx, pero estoy tratando de agregar funcionalidad Bluetooth, y eso implica llamar a un método no estático para poder acceder a la asociación de la actividad principal con la API de Android. Casi todo lo que he visto me dice que siga este procedimiento: - Crear una instancia de la actividad principal (entorno-> NewGlobalRef es la que estoy usando) - Obtener el método de la actividad y ejecutarlo (entorno-> GetObjectClass)

Y aquí está el código. En java tenemos lo siguiente (omitiendo cosas lógicas como onCreate, onResume, etc.):

public class TSP extends Cocos2dxActivity{ public void CnxAttempt(){ Log.e("TSP_BT","aTTEMPTING!"); } }

¡Eso es! Solo por ahora, solo quiero mostrar un mensaje de registro, confirmando que la función se ejecuta. Ahora, la parte divertida está en C ++:

static JNIEnv* getJNIEnv(void){ JNIEnv *env = 0; // get jni environment if (gJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK){ CCLog("Failed to get the environment using GetEnv()"); } if (gJavaVM->AttachCurrentThread(&env, 0) < 0){ CCLog("Failed to get the environment using AttachCurrentThread()"); } return env; } typedef struct JniMethodInfo_{ JNIEnv * env; // The environment jclass classID; // classID jmethodID methodID; // methodID } JniMethodInfo; // Struct that stores most of the important information to relate to Java code static bool getMethodInfo(JniMethodInfo &methodinfo, const char *methodName, const char *paramCode){ jmethodID methodID = 0; JNIEnv *pEnv = 0; jobject methodObject = NULL; bool bRet = false; do { pEnv = getJNIEnv(); if (! pEnv){ CCLog("getMethodInfo -- pEnv false"); break; } jclass localRef = pEnv->FindClass("org/cocos2dx/tsp/TSP"); if (localRef == NULL) { CCLog("getMethodInfo -- localRefCls false"); break; // exception thrown } gCallbackObject = pEnv->NewGlobalRef(localRef); if (gCallbackObject == NULL){ CCLog("getMethodInfo -- CallbackOBJ false"); break; } jclass classID = pEnv->GetObjectClass(methodObject); if (!classID){ CCLog("getMethodInfo -- classID false"); break; } methodID = pEnv->GetMethodID(classID, methodName, paramCode); if (!methodID){ CCLog("getMethodInfo -- methodID false"); break; } methodinfo.classID = classID; methodinfo.env = pEnv; methodinfo.methodID = methodID; CCLog("getMethodInfo -- methodinfo created"); bRet = true; } while(0); return bRet; } void CnxAttempt(){ JniMethodInfo methodInfo; // Creating a JniMethodInfo object to store all the data if (! getMethodInfo(methodInfo, "CnxAttempt", "()V")){ CCLog("getMethodInfo is FALSE :("); return; } methodInfo.env->CallVoidMethod(methodObject,methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); }

¡Y eso es! Al invocar CnxAttempt en C ++, pasa a BOOM porque no reconoce el método dentro de la clase Java y no puede acceder ... ¿Puede ayudarme alguien? Si algo no está claro, házmelo saber. ¡¡Muchas gracias de antemano!!


Crear una nueva referencia global no crea un nuevo objeto. La diferencia entre las referencias locales y globales (de los documentos) es:

Las referencias locales son válidas durante la duración de una llamada a método nativo y se liberan automáticamente después de que el método nativo regrese. Las referencias globales siguen siendo válidas hasta que se liberen explícitamente.

Si desea llamar un método no estático a un objeto, debe pasar el objeto al método nativo (si existe, ¿no debería existir la actividad principal?), Cree uno nuevo utilizando las funciones NewObject *. o llamando a algún método de fábrica.

A continuación, obtenga el objeto de clase del objeto, obtenga el ID de método y luego llame al método.