如何在Java中正确地从Android调用非静态函数?(混合物中的Cocos2Dx)
因此,我正在用Cocos2Dx开发一个小项目,但我正在尝试添加蓝牙功能,这意味着调用一个非静态方法,以便能够访问主活动与Android API的关联。我所看到的几乎所有东西都告诉我要遵循以下步骤: -创建主活动的实例(我正在使用的是environment->NewGlobalRef) -从活动中获取方法并执行它(环境->GetObjectClass) 这是代码。在java中,我们有以下内容(省略了onCreate、onResume等逻辑内容): 就这样!就目前而言,我只想显示一条日志消息,确认函数已执行。现在,有趣的部分是在C++:如何在Java中正确地从Android调用非静态函数?(混合物中的Cocos2Dx),android,android-activity,java-native-interface,cocos2d-x,non-static,Android,Android Activity,Java Native Interface,Cocos2d X,Non Static,因此,我正在用Cocos2Dx开发一个小项目,但我正在尝试添加蓝牙功能,这意味着调用一个非静态方法,以便能够访问主活动与Android API的关联。我所看到的几乎所有东西都告诉我要遵循以下步骤: -创建主活动的实例(我正在使用的是environment->NewGlobalRef) -从活动中获取方法并执行它(环境->GetObjectClass) 这是代码。在java中,我们有以下内容(省略了onCreate、onResume等逻辑内容): 就这样!就目前而言,我只想显示一条日志消息,确认函
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);
}
static JNIEnv*getJNIEnv(void){
JNIEV*env=0;
//获取jni环境
如果(gJavaVM->GetEnv((void**)和env,JNI_版本1_4)!=JNI_OK){
CCLog(“使用GetEnv()获取环境失败”);
}
如果(gJavaVM->AttachCurrentThread(&env,0)<0){
CCLog(“使用AttachCurrentThread()获取环境失败”);
}
返回环境;
}
typedef结构JniMethodInfo_{
JNIEnv*env;//环境
jclass classID;//classID
jmethodID;//methodID
}JniMethodInfo;//存储与Java代码相关的大部分重要信息的结构
静态bool getMethodInfo(JniMethodInfo&methodinfo,const char*methodName,const char*paramCode){
jmethodID=0;
JNIEnv*pEnv=0;
jobject methodObject=NULL;
布尔-布雷特=假;
做{
pEnv=getJNIEnv();
if(!pEnv){
CCLog(“getMethodInfo——pEnv false”);
打破
}
jclass localRef=pEnv->FindClass(“org/cocos2dx/tsp/tsp”);
if(localRef==NULL){
CCLog(“getMethodInfo--localRefCls false”);
break;//引发异常
}
gCallbackObject=pEnv->NewGlobalRef(localRef);
if(gCallbackObject==NULL){
CCLog(“getMethodInfo--CallbackOBJ false”);
打破
}
jclass classID=pEnv->GetObjectClass(methodObject);
如果(!classID){
CCLog(“getMethodInfo——classID false”);
打破
}
methodID=pEnv->GetMethodID(classID、methodName、paramCode);
如果(!methodID){
CCLog(“getMethodInfo--methodID false”);
打破
}
methodinfo.classID=classID;
methodinfo.env=pEnv;
methodinfo.methodID=methodID;
CCLog(“getMethodInfo——创建的methodinfo”);
bRet=真;
}而(0);
返回布雷特;
}
void cnxattent(){
JniMethodInfo methodInfo;//创建一个JniMethodInfo对象来存储所有数据
如果(!getMethodInfo(methodInfo,cnxattent,“()V”)){
CCLog(“getMethodInfo为FALSE:(”);
返回;
}
methodInfo.env->CallVoidMethod(methodObject,methodInfo.methodID);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
在C++调用CnxAttempt时,它会发生BooD,因为它不识别java类中的方法,不能到达它。
有人能帮我一把吗?如果有什么不清楚的地方,请告诉我。提前多谢!!创建新的全局引用不会创建新对象。本地引用和全局引用(来自文档)之间的区别是: 本地引用在本机方法调用期间有效,并且在本机方法返回后自动释放。全局引用在显式释放之前保持有效 如果要对对象调用非静态方法,则需要将该对象传递给本机方法(如果存在-主活动是否已经存在?),使用NewObject*函数创建一个新方法,或者通过调用某些工厂方法
然后获取对象的class对象,获取methodID,然后调用该方法。感谢您的回复!我实际上停止使用NewGlobalRef函数,开始使用NewObject,但结果是一样的。在对该主题进行了更多研究和对代码进行了几次调整后,我通过alter成功地获得了非静态函数按照定义的顺序,下面这个例子:我现在必须面对的是,从主要活动中使用任何类型的外部功能(如蓝牙)都会使我的应用程序像快照一样崩溃:(但这是另一个问题……可能。非常感谢!
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);
}