android|android NDK 实用学习(五)-c++端调用java接口

1,阅读此文章前请阅读前面文章,以免阅读出现障碍;
android NDK 实用学习(一)-获取java端类及其类变量
【android|android NDK 实用学习(五)-c++端调用java接口】android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值
android NDK 实用学习(三)- java端类对象的构造及使用
android NDK 实用学习(四)-类缓存
2,java端类接口定义:

1public class RTKNativeManager { 2// 其他接口 3 4// 开给c++端的接口 5public static void notifyResolveResult(short id, TestSetData setData) { 6Log.d(TAG, "notifyResult start"); 7 8boolean bb = setData.bData; 9int ii = setData.iData; 10String msg = String.format("get msg: %b-%d", bb, ii); 11Log.d(TAG, msg); 12 13Log.d(TAG, "notifyResult end!"); 14} 15 }

3, c++ 端获取类接口:

1// 获取类 2jclass jnativeMgr = NULL; 3jmethodID jnotifyKQResolveResult = NULL; 4 5// 获取类和方法 6jnativeMgr = env->FindClass("com/dasea/test/core/RTKNativeManager"); 7 8jnotifyKQResolveResult = env->GetStaticMethodID( 9jnativeMgr, "notifyKQResolveResult", "(SLcom/dasea/test/core/TestSetData; )V");


3, 使用:
1 void Jni_Call_Java_notifyResolveResult(short id){ 2DEBUG_OUT(" WHAT QINGKUANG!!"); 3 4JNIEnv* env = JniHelper::getEnv(); 5if (NULL == env) 6{ 7DEBUG_OUT(" ENV IS NULL!"); 8return ; 9} 10 11// 获取类和方法 12jclass jnativeMgr = env->FindClass("com/dasea/test/core/RTKNativeManager"); 13if (NULL == jnativeMgr) 14{ 15DEBUG_OUT("Native mgr is NULL; !"); 16} 17 18// 构造jni实例 19jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData"); 20if(NULL == jcSetDataMgr){ 21DEBUG_OUT("Not find class!"); 22return ; 23} 24 25DEBUG_OUT("AllocObject object !"); 26jmethodID initID = env->GetMethodID(jcSetDataMgr, "", "()V"); 27jobject jresult = env->NewObject(jcSetDataMgr, initID); 28 29if (NULL == jresult || env->ExceptionOccurred()) 30{ 31DEBUG_OUT("Construct object failed!"); 32return ; 33} 34 35// 成员变量赋值,可以参考前面几篇文章 36 37DEBUG_OUT("CallStaticVoidMethod"); 38 39// 调用静态方法 40env->CallStaticVoidMethod(jnativeMgr, jnotifyKQResolveResult , 20, jresult); 41 }


4,上面代码中有Jnihelper类,代码如下:
1 #ifndef __ANDROID_JNI_HELPER_H__ 2 #define __ANDROID_JNI_HELPER_H__ 3 4 #include 5 #include 6 7 typedef struct JniMethodInfo_ { 8JNIEnv * env; 9jclass classID; 10jmethodID methodID; 11 } JniMethodInfo; 12 13 class JniHelper { 14 public: 15static void setJavaVM(JavaVM *javaVM); 16static JavaVM* getJavaVM(); 17static JNIEnv* getEnv(); 18 19static bool setClassLoaderFrom(jobject activityInstance); 20static bool getStaticMethodInfo(JniMethodInfo &methodinfo, 21const char *className, const char *methodName, 22const char *paramCode); 23static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, 24const char *methodName, const char *paramCode); 25 26static std::string jstring2string(jstring str); 27 28static jmethodID loadclassMethod_methodID; 29static jobject classloader; 30 31 private: 32static JNIEnv* cacheEnv(JavaVM* jvm); 33 34static bool getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo, 35const char *className, const char *methodName, 36const char *paramCode); 37 38static JavaVM* _psJavaVM; 39 }; 40 41 #endif // __ANDROID_JNI_HELPER_H__

android|android NDK 实用学习(五)-c++端调用java接口
文章图片
android|android NDK 实用学习(五)-c++端调用java接口
文章图片
1 /**************************************************************************** 2Copyright (c) 2010-2012 cocos2d-x.org 3Copyright (c) 2013-2014 Chukong Technologies Inc. 4 5http://www.cocos2d-x.org 6 7Permission is hereby granted, free of charge, to any person obtaining a copy 8of this software and associated documentation files (the "Software"), to deal 9in the Software without restriction, including without limitation the rights 10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11copies of the Software, and to permit persons to whom the Software is 12furnished to do so, subject to the following conditions: 13 14The above copyright notice and this permission notice shall be included in 15all copies or substantial portions of the Software. 16 17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23THE SOFTWARE. 24****************************************************************************/ 25 #include "JniHelper.h" 26 #include 27 #include 28 #include "CBasePara.h" 29 30 static pthread_key_t g_key; 31 32 jclass _getClassID(const char *className) { 33if (NULL == className) { 34return NULL; 35} 36 37JNIEnv* env = JniHelper::getEnv(); 38 39jstring _jstrClassName = env->NewStringUTF(className); 40 41 //jclass _clazz = (jclass) env->CallObjectMethod(JniHelper::classloader, 42 //JniHelper::loadclassMethod_methodID, 43 //_jstrClassName); 44 45jclass _clazz = (jclass) env->FindClass(className); 46 47if (NULL == _clazz) { 48DEBUG_OUT("Classloader failed to find class of %s", className); 49env->ExceptionClear(); 50} 51 52env->DeleteLocalRef(_jstrClassName); 53 54return _clazz; 55 } 56 57 JavaVM* JniHelper::_psJavaVM = NULL; 58 jmethodID JniHelper::loadclassMethod_methodID = NULL; 59 jobject JniHelper::classloader = NULL; 60 61 JavaVM* JniHelper::getJavaVM() { 62pthread_t thisthread = pthread_self(); 63//LOGD("JniHelper::getJavaVM(), pthread_self() = %ld", thisthread); 64return _psJavaVM; 65 } 66 67 void JniHelper::setJavaVM(JavaVM *javaVM) { 68pthread_t thisthread = pthread_self(); 69//LOGD("JniHelper::setJavaVM(%p), pthread_self() = %ld", javaVM, thisthread); 70_psJavaVM = javaVM; 71 72pthread_key_create(&g_key, NULL); 73 } 74 75 JNIEnv* JniHelper::cacheEnv(JavaVM* jvm) { 76JNIEnv* _env = NULL; 77// get jni environment 78jint ret = jvm->GetEnv((void**) &_env, JNI_VERSION_1_4); 79 80switch (ret) { 81case JNI_OK: 82// Success! 83pthread_setspecific(g_key, _env); 84return _env; 85 86case JNI_EDETACHED: 87// Thread not attached 88 89// TODO : If calling AttachCurrentThread() on a native thread 90// must call DetachCurrentThread() in future. 91// see: http://developer.android.com/guide/practices/design/jni.html 92 93if (jvm->AttachCurrentThread(&_env, NULL) < 0) { 94DEBUG_OUT( 95"Failed to get the environment using AttachCurrentThread()"); 96 97return NULL; 98} else { 99// Success : Attached and obtained JNIEnv! 100pthread_setspecific(g_key, _env); 101return _env; 102} 103 104case JNI_EVERSION: 105// Cannot recover from this error 106DEBUG_OUT("JNI interface version 1.4 not supported"); 107default: 108DEBUG_OUT("Failed to get the environment using GetEnv()"); 109return NULL; 110} 111 } 112 113 JNIEnv* JniHelper::getEnv() { 114JNIEnv *_env = (JNIEnv *) pthread_getspecific(g_key); 115if (_env == NULL) 116_env = JniHelper::cacheEnv(_psJavaVM); 117return _env; 118 } 119 120 bool JniHelper::setClassLoaderFrom(jobject activityinstance) { 121JniMethodInfo _getclassloaderMethod; 122if (!JniHelper::getMethodInfo_DefaultClassLoader(_getclassloaderMethod, 123"android/content/Context", "getClassLoader", 124"()Ljava/lang/ClassLoader; ")) { 125return false; 126} 127 128jobject _c = JniHelper::getEnv()->CallObjectMethod(activityinstance, 129_getclassloaderMethod.methodID); 130 131if (NULL == _c) { 132return false; 133} 134 135JniMethodInfo _m; 136if (!JniHelper::getMethodInfo_DefaultClassLoader(_m, 137"java/lang/ClassLoader", "loadClass", 138"(Ljava/lang/String; )Ljava/lang/Class; ")) { 139return false; 140} 141 142JniHelper::classloader = JniHelper::getEnv()->NewGlobalRef(_c); 143JniHelper::loadclassMethod_methodID = _m.methodID; 144 145return true; 146 } 147 148 bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo, 149const char *className, const char *methodName, const char *paramCode) { 150if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) { 151return false; 152} 153 154JNIEnv *env = JniHelper::getEnv(); 155if (!env) { 156DEBUG_OUT("Failed to get JNIEnv"); 157return false; 158} 159 160jclass classID = _getClassID(className); 161if (!classID) { 162DEBUG_OUT("Failed to find class %s", className); 163env->ExceptionClear(); 164return false; 165} 166 167jmethodID methodID = env->GetStaticMethodID(classID, methodName, paramCode); 168if (!methodID) { 169DEBUG_OUT("Failed to find static method id of %s", methodName); 170env->ExceptionClear(); 171return false; 172} 173 174methodinfo.classID = classID; 175methodinfo.env = env; 176methodinfo.methodID = methodID; 177return true; 178 } 179 180 bool JniHelper::getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo, 181const char *className, const char *methodName, const char *paramCode) { 182if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) { 183return false; 184} 185 186JNIEnv *env = JniHelper::getEnv(); 187if (!env) { 188return false; 189} 190 191jclass classID = env->FindClass(className); 192if (!classID) { 193DEBUG_OUT("Failed to find class %s", className); 194env->ExceptionClear(); 195return false; 196} 197 198jmethodID methodID = env->GetMethodID(classID, methodName, paramCode); 199if (!methodID) { 200DEBUG_OUT("Failed to find method id of %s", methodName); 201env->ExceptionClear(); 202return false; 203} 204 205methodinfo.classID = classID; 206methodinfo.env = env; 207methodinfo.methodID = methodID; 208 209return true; 210 } 211 212 bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo, const char *className, 213const char *methodName, const char *paramCode) { 214if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) { 215return false; 216} 217 218JNIEnv *env = JniHelper::getEnv(); 219if (!env) { 220return false; 221} 222 223jclass classID = _getClassID(className); 224if (!classID) { 225DEBUG_OUT("Failed to find class %s", className); 226env->ExceptionClear(); 227return false; 228} 229 230jmethodID methodID = env->GetMethodID(classID, methodName, paramCode); 231if (!methodID) { 232DEBUG_OUT("Failed to find method id of %s", methodName); 233env->ExceptionClear(); 234return false; 235} 236 237methodinfo.classID = classID; 238methodinfo.env = env; 239methodinfo.methodID = methodID; 240 241return true; 242 } 243 244 std::string JniHelper::jstring2string(jstring jstr) { 245if (jstr == NULL) { 246return ""; 247} 248 249JNIEnv *env = JniHelper::getEnv(); 250if (!env) { 251return NULL; 252} 253 254const char* chars = env->GetStringUTFChars(jstr, NULL); 255std::string ret(chars); 256env->ReleaseStringUTFChars(jstr, chars); 257 258return ret; 259 }

View Code 5,在c++端定义JNI_OnLoad接口:
1 jint JNI_OnLoad(JavaVM *vm, void *reserved) { 2JniHelper::setJavaVM(vm); 3 4return JNI_VERSION_1_4; 5 }

6,注意:
如果使用c++端调用java端接口时,就需要通过JniHelper::getEnv()接口获取env。




转载于:https://www.cnblogs.com/dhf-0214/p/4612946.html

    推荐阅读