cocos2d-x中jni总结

| 分类 cocos2d-x  | 标签 cocos2d-x 

本文为xiedantibu在学习cocos2d-x的笔记,转载请注明作者及出处! ###目录 —-     JNIEnv*指针实例的获取
    jstring以及std::string之间的转换
    获取方法的信息
    C++回调JAVA的静态方法以及普通方法
    java回调c++实现的方法


####JNIEnv*环境变量的获取

  1. JNIEnv* JniHelper::getEnv() {
  2. JNIEnv *_env = (JNIEnv *)pthread_getspecific(g_key);
  3. if (_env == nullptr)
  4. _env = JniHelper::cacheEnv(_psJavaVM);
  5. return _env;
  6. }

####jstring以及std::string之间的转换

  • jstring转成std::string

    1. std::string JniHelper::jstring2string(jstring jstr)
    2. {
    3. if (jstr == nullptr) {
    4. return "";
    5. }
    6. JNIEnv *env = JniHelper::getEnv();
    7. if (!env) {
    8. return nullptr;
    9. }
    10. const char* chars = env->GetStringUTFChars(jstr, nullptr);//将jstring转成char*
    11. std::string ret(chars);
    12. env->ReleaseStringUTFChars(jstr, chars);//删除引用
    13. return ret;
    14. } ---
  • std::string转成jstring

    1. JNIEnv* env = cocos2d::JniHelper::getEnv();
    2. jstring _jstrClassName = env->NewStringUTF(className);//将std::string转成jstring ---
  • jstringtostring相互转换的例子

    1. public static String getItem(String key) {//Cocos2dxLocalStorage.java类中的方法,传入一个key
    2. return ret == null ? "" : ret;//返回String
    3. }
    4. //下面是在c++中回调这个方法
    5. std::string localStorageGetItem( const std::string& key )
    6. {
    7. assert( _initialized );
    8. JniMethodInfo t;//一个struct含有JNIEnv * ,jclass,jmethodID属性
    9. std::string ret;
    10. if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "getItem", "(Ljava/lang/String;)Ljava/lang/String;")) {//获取getItem类id,以及方法id
    11. jstring jkey = t.env->NewStringUTF(key.c_str());//将std::string转成jstring
    12. jstring jret = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID, jkey);//传入获取的类id,方法id,回调getItem方法,返回jstring
    13. ret = JniHelper::jstring2string(jret);//jstring转成std::string
    14. t.env->DeleteLocalRef(jret);//删除引用
    15. t.env->DeleteLocalRef(jkey);//删除引用
    16. t.env->DeleteLocalRef(t.classID);//删除引用
    17. }
    18. return ret;
    19. } --- <a id='getMethodInfo' name='getMethodInfo'> </a> ####[获取方法的信息](#top) ---
  • 获取静态方法信息static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);

  • 获取常规方法信息static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);

    className表示的是包名+类名,methodName表示的是调用的方法名,paramCode表示的是传入参数以及返回值类型,它的格式为:(参数)返回类型 ,不管是常规还是静态方法最终都把相关信息保存在methodinfo中.

  • paramCode参数类型书写格式对应表

参数类型 参数简写
boolean Z
byte B
char C
short S
int I
long J
float F
double D
void V
Object Ljava/lang/String;
Array [Ljava/lang/String;
  1. 注意Object以及Array两种类型之后的分号。示例:(IIII)V //表示传入参数是4个整数,返回值为void。ILjava/lang/String;I //表示的是传入参数为(int,string,int)

####C++回调JAVA的静态方法以及普通方法

JNIEvn*有一系列的CallStatic[返回类型]Method、Call[返回类型]Method方法,针对不同的函数返回类型选择性调用。

  • 返回类型为void时候:
  • CallStaticVoidMethod ———void返回类型
  • CallVoidMethod ———void返回类型

  • 函数名以及函数返回值类型对应表
函数名 函数返回值类型
Void void
Object jobject
Boolean jboolean
Byte jbyte
Char jchar
Short jshort
Int jint
Long jlong
Float jfloat
Double jdouble

  • 回调普通方法以及静态方法最主要的区别在于传入的参数:
  • jniMethodInfo.env->CallVoidMethod(jobject jobj,jmethodID methodId,..需要传入的参数..)
  • jniMethodInfo.env->CallStaticObjectMethod(jclass jclassid,jmethodID methodId,..需要传入的参数..)
  • 以上两个方法最主要的区别在于第一个参数的不同,普通方法传入的是jobject,而静态方法传入的是jclass。在调用普通Method的时候必须先通过方法jniMethodInfo.env->CallStaticObjectMethod(jniMethodInfo.classID, jniMethodInfo.methodID,...);获取jobject实例,至于静态方法则不需要那么麻烦。

  • 普通方法回调例子

    1. bool isHave = JniHelper::getStaticMethodInfo(minfoDeviceUuid,"包名","getInstance","()Lcom/u9time/buyumalatang/activity/NewArcadeFishActivity;");
    2. jobject jobj;//获取实例
    3. if (isHave) {
    4. jobj = minfoDeviceUuid.env->CallStaticObjectMethod(minfoDeviceUuid.classID, minfoDeviceUuid.methodID);//调用CallStaticObjectMethod方法获取实例
    5. bool isHaveUuid = JniHelper::getMethodInfo(minfoDeviceUuid, "com/u9time/buyumalatang/activity/NewArcadeFishActivity", "showSubWebView", "(Ljava/lang/String;Ljava/lang/String;)V");//获取普通方法信息
    6. if(isHaveUuid){
    7. jstring strUrl = str2jstring(minfoDeviceUuid.env, CCUserDefault::sharedUserDefault()->getStringForKey("AU").c_str());
    8. jstring strWebviewType = str2jstring(minfoDeviceUuid.env, "protocol");
    9. minfoDeviceUuid.env->CallVoidMethod(jobj, minfoDeviceUuid.methodID, strUrl, strWebviewType);//回调普通方法
    10. }
    11. } ---
  • 静态方法回调例子

    1. void localStorageSetItem( const std::string& key, const std::string& value)
    2. {
    3. assert( _initialized );
    4. JniMethodInfo t;
    5. if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxLocalStorage", "setItem", "(Ljava/lang/String;Ljava/lang/String;)V")) {//获取setItem方法信息
    6. jstring jkey = t.env->NewStringUTF(key.c_str());
    7. jstring jvalue = t.env->NewStringUTF(value.c_str());
    8. t.env->CallStaticVoidMethod(t.classID, t.methodID, jkey, jvalue);//回调方法
    9. t.env->DeleteLocalRef(jkey);
    10. t.env->DeleteLocalRef(jvalue);
    11. t.env->DeleteLocalRef(t.classID);
    12. }
    13. }

####java回调c++实现的方法

  • 没有返回值的回调

    1. private static native void nativeInsertText(final String text);
    2. extern "C" {
    3. JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInsertText(JNIEnv* env, jobject thiz, jstring text) {//注意命名,以及方法包含在extern "C"中
    4. const char* pszText = env->GetStringUTFChars(text, NULL);
    5. cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText, strlen(pszText));
    6. env->ReleaseStringUTFChars(text, pszText);
    7. }
    8. }
  • 含有返回值的回调

    1. private static native int[] getGLContextAttrs();
    2. extern "C" {
    3. jintArray Java_org_cocos2dx_lib_Cocos2dxActivity_getGLContextAttrs(JNIEnv* env, jobject thiz)
    4. {
    5. cocos_android_app_init(env, thiz);
    6. cocos2d::Application::getInstance()->initGLContextAttrs();
    7. GLContextAttrs _glContextAttrs = GLView::getGLContextAttrs();
    8. int tmp[6] = {_glContextAttrs.redBits, _glContextAttrs.greenBits, _glContextAttrs.blueBits,
    9. _glContextAttrs.alphaBits, _glContextAttrs.depthBits, _glContextAttrs.stencilBits};
    10. jintArray glContextAttrsJava = env->NewIntArray(6);
    11. env->SetIntArrayRegion(glContextAttrsJava, 0, 6, tmp);
    12. return glContextAttrsJava;
    13. }
    14. }

青春是一场大雨,即使感冒了,还盼回头再淋一次...image...微笑永远是一个人身上最好看的东西...


PREVIOUS     NEXT