Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中正确地从Android调用非静态函数?(混合物中的Cocos2Dx)_Android_Android Activity_Java Native Interface_Cocos2d X_Non Static - Fatal编程技术网

如何在Java中正确地从Android调用非静态函数?(混合物中的Cocos2Dx)

如何在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等逻辑内容): 就这样!就目前而言,我只想显示一条日志消息,确认函

因此,我正在用Cocos2Dx开发一个小项目,但我正在尝试添加蓝牙功能,这意味着调用一个非静态方法,以便能够访问主活动与Android API的关联。我所看到的几乎所有东西都告诉我要遵循以下步骤: -创建主活动的实例(我正在使用的是environment->NewGlobalRef) -从活动中获取方法并执行它(环境->GetObjectClass)

这是代码。在java中,我们有以下内容(省略了onCreate、onResume等逻辑内容):

就这样!就目前而言,我只想显示一条日志消息,确认函数已执行。现在,有趣的部分是在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);
    }
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);
    }