(ps : 好久都没有关注博客了,现在从事2dx游戏开发,以后专心搞C++与2dx)
我们都知道java与C可以相互调用,Java调用C写的代码一般是定义native方法,然后去编译生成.h头文件
再由c来实现,然后编译运行。
2dx里面为我们提供了一个JniHelper类,来满足与Java层的数据交互,JniHelper可以调用java层的动静态方法,
当然还有native方法,先来看看源码:
#include "JniHelper.h" #include <android/log.h> #include <string.h> #if 1 #define LOG_TAG "JniHelper" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #else #define LOGD(...) #endif #define JAVAVM cocos2d::JniHelper::getJavaVM() using namespace std; extern "C" { ////////////////////////////////////////////////////////////////////////// // java vm helper function ////////////////////////////////////////////////////////////////////////// static bool getEnv(JNIEnv **env) { bool bRet = false; do { if (JAVAVM->GetEnv((void**)env, JNI_VERSION_1_4) != JNI_OK) { LOGD("Failed to get the environment using GetEnv()"); break; } if (JAVAVM->AttachCurrentThread(env, 0) < 0) { LOGD("Failed to get the environment using AttachCurrentThread()"); break; } bRet = true; } while (0); return bRet; } static jclass getClassID_(const char *className, JNIEnv *env) { JNIEnv *pEnv = env; jclass ret = 0; do { if (! pEnv) { if (! getEnv(&pEnv)) { break; } } ret = pEnv->FindClass(className); if (! ret) { LOGD("Failed to find class of %s", className); break; } } while (0); return ret; } static bool getStaticMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode) { jmethodID methodID = 0; JNIEnv *pEnv = 0; bool bRet = false; do { if (! getEnv(&pEnv)) { break; } jclass classID = getClassID_(className, pEnv); methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode); if (! methodID) { LOGD("Failed to find static method id of %s", methodName); break; } methodinfo.classID = classID; methodinfo.env = pEnv; methodinfo.methodID = methodID; bRet = true; } while (0); return bRet; } static bool getMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode) { jmethodID methodID = 0; JNIEnv *pEnv = 0; bool bRet = false; do { if (! getEnv(&pEnv)) { break; } jclass classID = getClassID_(className, pEnv); methodID = pEnv->GetMethodID(classID, methodName, paramCode); if (! methodID) { LOGD("Failed to find method id of %s", methodName); break; } methodinfo.classID = classID; methodinfo.env = pEnv; methodinfo.methodID = methodID; bRet = true; } while (0); return bRet; } static string jstring2string_(jstring jstr) { if (jstr == NULL) { return ""; } JNIEnv *env = 0; if (! getEnv(&env)) { return 0; } const char* chars = env->GetStringUTFChars(jstr, NULL); string ret(chars); env->ReleaseStringUTFChars(jstr, chars); return ret; } } NS_CC_BEGIN JavaVM* JniHelper::m_psJavaVM = NULL; JavaVM* JniHelper::getJavaVM() { return m_psJavaVM; } void JniHelper::setJavaVM(JavaVM *javaVM) { m_psJavaVM = javaVM; } string JniHelper::m_externalAssetPath; const char* JniHelper::getExternalAssetPath() { return m_externalAssetPath.c_str(); } void JniHelper::setExternalAssetPath(const char * externalAssetPath) { m_externalAssetPath = externalAssetPath; } jclass JniHelper::getClassID(const char *className, JNIEnv *env) { return getClassID_(className, env); } bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode) { return getStaticMethodInfo_(methodinfo, className, methodName, paramCode); } bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode) { return getMethodInfo_(methodinfo, className, methodName, paramCode); } string JniHelper::jstring2string(jstring str) { return jstring2string_(str); } NS_CC_END
getStaticMethodInfo、getMethodInfo
第一个调用Java静态方法的方法:
getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)
----
第一个参数为JniMethodInfo,为一个容器类,表示当前调用的方法
第二个参数为调用Java方法类的全名
第三个参数为调用java的方法名
第三个参数为方法的参数类型,(参数类型1;参数类型2;..)返回值 java与Jni对应的参数类型如下:
java jni(c)
String Ljava/lang/String
void V
int I
boolean Z
使用步骤:
1,getStaticMethodInfo,获取需要调用的java方法信息
2,再使用JniMethodInfo的env调用执行Java的静态方法
getMethodInfo:调用的是java层的动态方法,其他的都一样