How to make a proper call from Android to non-static function in Java? (Cocos2Dx in the mix)

So, I'm developing a small project with Cocos2Dx, but I'm trying to add Bluetooth functionality, and this implies calling a non-static method to be able to access the Main Activity association for the Android API. Almost everything I saw tells me to follow this procedure: - Create an instance of the main action (environment β†’ NewGlobalRef - the one I use) - Get the method from the action and execute it (environment-> GetObjectClass)

And here is the code. In java, we have the following (excluding logical elements such as onCreate, onResume, etc.):

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

What is it! At the moment, I want to show a log message confirming that the function has completed. Now the interesting part is in 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); } 

And this! When calling CnxAttempt in C ++, it goes into BOOM because it does not recognize the method in the Java class and cannot reach it ... Can someone give me a hand? If something is unclear, let me know. Thanks for the bunch in advance!

+4
source share
1 answer

Creating a new global link does not create a new object. The difference between local and global links (from documents):

Local references are valid for the duration of the call to the native method and are automatically freed after returning the native method. Global links remain valid until they are explicitly released.

If you want to call a non-static method on an object, you need to pass the object to your own method (if it exists - shouldn't the main activity already exist?), Create a new one using NewObject *, or by calling some factory method.

Then get the object of the object class, get the methodID, and then call the method.

+3
source

Source: https://habr.com/ru/post/1399795/


All Articles