ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何从Android到Java中的非静态函数进行正确调用? (混合中的Cocos2Dx)

2019-06-30 08:11:09  阅读:185  来源: 互联网

标签:android android-activity cocos2d-x java-native-interface non-static


所以我正在用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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有