如何从Android到Java中的非静态函数进行正确调用? (混合中的Cocos2Dx)
作者:互联网
所以我正在用Cocos2Dx开发一个小项目,但我正在尝试添加蓝牙功能,这意味着调用非静态方法可以访问Main Activity与Android API的关联.我见过的几乎所有内容都告诉我遵循这个程序:
– 创建主要活动的实例(environment-> NewGlobalRef是我正在使用的实例)
– 从活动中获取方法并执行它(environment-> GetObjectClass)
这是代码.在java中我们有以下内容(省略onCreate,onResume等逻辑内容):
public class TSP extends Cocos2dxActivity{
public void CnxAttempt(){
Log.e("TSP_BT","aTTEMPTING!");
}
}
而已!就目前而言,我只想显示一条Log消息,确认该函数已执行.现在,有趣的部分是在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);
}
就是这样!在C上调用CnxAttempt时,它会转到BOOM,因为它无法识别Java类中的方法而无法访问它…
有人可以帮我一把吗?如果不清楚,请告诉我.先谢谢了!
解决方法:
创建新的全局引用不会创建新对象.本地和全局引用(来自文档)之间的区别是:
Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. Global references remain valid until they are explicitly freed.
如果要对对象调用非静态方法,则需要将对象传递给本机方法(如果存在 – 主活动是否应该存在?),使用NewObject *函数创建一个新方法,或者通过调用一些工厂方法.
然后获取对象的类对象,获取methodID然后调用该方法.
标签:android,android-activity,cocos2d-x,java-native-interface,non-static 来源: https://codeday.me/bug/20190630/1334767.html