1,阅读此文章前请阅读前面文章,以免阅读出现障碍;

android NDK 实用学习(一)-获取java端类及其类变量

android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值

android NDK 实用学习(三)- java端类对象的构造及使用

android NDK 实用学习(四)-类缓存

2,java端类接口定义:

  public class RTKNativeManager {
// 其他接口 // 开给c++端的接口
public static void notifyResolveResult(short id, TestSetData setData) {
Log.d(TAG, "notifyResult start"); boolean bb = setData.bData;
int ii = setData.iData;
String msg = String.format("get msg: %b-%d", bb, ii);
Log.d(TAG, msg); Log.d(TAG, "notifyResult end!");
}
}
3, c++ 端获取类接口:
     // 获取类
jclass jnativeMgr = NULL;
jmethodID jnotifyKQResolveResult = NULL; // 获取类和方法
jnativeMgr = env->FindClass("com/dasea/test/core/RTKNativeManager"); jnotifyKQResolveResult = env->GetStaticMethodID(
jnativeMgr, "notifyKQResolveResult", "(SLcom/dasea/test/core/TestSetData;)V");

3, 使用:

 void Jni_Call_Java_notifyResolveResult(short id){
DEBUG_OUT(" WHAT QINGKUANG!!"); JNIEnv* env = JniHelper::getEnv();
if (NULL == env)
{
DEBUG_OUT(" ENV IS NULL!");
return ;
} // 获取类和方法
jclass jnativeMgr = env->FindClass("com/dasea/test/core/RTKNativeManager");
if (NULL == jnativeMgr)
{
DEBUG_OUT("Native mgr is NULL;!");
} // 构造jni实例
jclass jcSetDataMgr = env->FindClass("com/dasea/test/core/TestSetData");
if(NULL == jcSetDataMgr){
DEBUG_OUT("Not find class!");
return ;
} DEBUG_OUT("AllocObject object !");
jmethodID initID = env->GetMethodID(jcSetDataMgr, "<init>", "()V");
jobject jresult = env->NewObject(jcSetDataMgr, initID); if (NULL == jresult || env->ExceptionOccurred())
{
DEBUG_OUT("Construct object failed!");
return ;
} // 成员变量赋值,可以参考前面几篇文章 DEBUG_OUT("CallStaticVoidMethod"); // 调用静态方法
env->CallStaticVoidMethod(jnativeMgr, jnotifyKQResolveResult , , jresult);
}

4,上面代码中有Jnihelper类,代码如下:

 #ifndef __ANDROID_JNI_HELPER_H__
#define __ANDROID_JNI_HELPER_H__ #include <jni.h>
#include <string> typedef struct JniMethodInfo_ {
JNIEnv * env;
jclass classID;
jmethodID methodID;
} JniMethodInfo; class JniHelper {
public:
static void setJavaVM(JavaVM *javaVM);
static JavaVM* getJavaVM();
static JNIEnv* getEnv(); static bool setClassLoaderFrom(jobject activityInstance);
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); static std::string jstring2string(jstring str); static jmethodID loadclassMethod_methodID;
static jobject classloader; private:
static JNIEnv* cacheEnv(JavaVM* jvm); static bool getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo,
const char *className, const char *methodName,
const char *paramCode); static JavaVM* _psJavaVM;
}; #endif // __ANDROID_JNI_HELPER_H__
 /****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc. http://www.cocos2d-x.org Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "JniHelper.h"
#include <string.h>
#include <pthread.h>
#include "CBasePara.h" static pthread_key_t g_key; jclass _getClassID(const char *className) {
if (NULL == className) {
return NULL;
} JNIEnv* env = JniHelper::getEnv(); jstring _jstrClassName = env->NewStringUTF(className); // jclass _clazz = (jclass) env->CallObjectMethod(JniHelper::classloader,
// JniHelper::loadclassMethod_methodID,
// _jstrClassName); jclass _clazz = (jclass) env->FindClass(className); if (NULL == _clazz) {
DEBUG_OUT("Classloader failed to find class of %s", className);
env->ExceptionClear();
} env->DeleteLocalRef(_jstrClassName); return _clazz;
} JavaVM* JniHelper::_psJavaVM = NULL;
jmethodID JniHelper::loadclassMethod_methodID = NULL;
jobject JniHelper::classloader = NULL; JavaVM* JniHelper::getJavaVM() {
pthread_t thisthread = pthread_self();
//LOGD("JniHelper::getJavaVM(), pthread_self() = %ld", thisthread);
return _psJavaVM;
} void JniHelper::setJavaVM(JavaVM *javaVM) {
pthread_t thisthread = pthread_self();
//LOGD("JniHelper::setJavaVM(%p), pthread_self() = %ld", javaVM, thisthread);
_psJavaVM = javaVM; pthread_key_create(&g_key, NULL);
} JNIEnv* JniHelper::cacheEnv(JavaVM* jvm) {
JNIEnv* _env = NULL;
// get jni environment
jint ret = jvm->GetEnv((void**) &_env, JNI_VERSION_1_4); switch (ret) {
case JNI_OK:
// Success!
pthread_setspecific(g_key, _env);
return _env; case JNI_EDETACHED:
// Thread not attached // TODO : If calling AttachCurrentThread() on a native thread
// must call DetachCurrentThread() in future.
// see: http://developer.android.com/guide/practices/design/jni.html if (jvm->AttachCurrentThread(&_env, NULL) < ) {
DEBUG_OUT(
"Failed to get the environment using AttachCurrentThread()"); return NULL;
} else {
// Success : Attached and obtained JNIEnv!
pthread_setspecific(g_key, _env);
return _env;
} case JNI_EVERSION:
// Cannot recover from this error
DEBUG_OUT("JNI interface version 1.4 not supported");
default:
DEBUG_OUT("Failed to get the environment using GetEnv()");
return NULL;
}
} JNIEnv* JniHelper::getEnv() {
JNIEnv *_env = (JNIEnv *) pthread_getspecific(g_key);
if (_env == NULL)
_env = JniHelper::cacheEnv(_psJavaVM);
return _env;
} bool JniHelper::setClassLoaderFrom(jobject activityinstance) {
JniMethodInfo _getclassloaderMethod;
if (!JniHelper::getMethodInfo_DefaultClassLoader(_getclassloaderMethod,
"android/content/Context", "getClassLoader",
"()Ljava/lang/ClassLoader;")) {
return false;
} jobject _c = JniHelper::getEnv()->CallObjectMethod(activityinstance,
_getclassloaderMethod.methodID); if (NULL == _c) {
return false;
} JniMethodInfo _m;
if (!JniHelper::getMethodInfo_DefaultClassLoader(_m,
"java/lang/ClassLoader", "loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;")) {
return false;
} JniHelper::classloader = JniHelper::getEnv()->NewGlobalRef(_c);
JniHelper::loadclassMethod_methodID = _m.methodID; return true;
} bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo,
const char *className, const char *methodName, const char *paramCode) {
if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) {
return false;
} JNIEnv *env = JniHelper::getEnv();
if (!env) {
DEBUG_OUT("Failed to get JNIEnv");
return false;
} jclass classID = _getClassID(className);
if (!classID) {
DEBUG_OUT("Failed to find class %s", className);
env->ExceptionClear();
return false;
} jmethodID methodID = env->GetStaticMethodID(classID, methodName, paramCode);
if (!methodID) {
DEBUG_OUT("Failed to find static method id of %s", methodName);
env->ExceptionClear();
return false;
} methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID;
return true;
} bool JniHelper::getMethodInfo_DefaultClassLoader(JniMethodInfo &methodinfo,
const char *className, const char *methodName, const char *paramCode) {
if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) {
return false;
} JNIEnv *env = JniHelper::getEnv();
if (!env) {
return false;
} jclass classID = env->FindClass(className);
if (!classID) {
DEBUG_OUT("Failed to find class %s", className);
env->ExceptionClear();
return false;
} jmethodID methodID = env->GetMethodID(classID, methodName, paramCode);
if (!methodID) {
DEBUG_OUT("Failed to find method id of %s", methodName);
env->ExceptionClear();
return false;
} methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID; return true;
} bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo, const char *className,
const char *methodName, const char *paramCode) {
if ((NULL == className) || (NULL == methodName) || (NULL == paramCode)) {
return false;
} JNIEnv *env = JniHelper::getEnv();
if (!env) {
return false;
} jclass classID = _getClassID(className);
if (!classID) {
DEBUG_OUT("Failed to find class %s", className);
env->ExceptionClear();
return false;
} jmethodID methodID = env->GetMethodID(classID, methodName, paramCode);
if (!methodID) {
DEBUG_OUT("Failed to find method id of %s", methodName);
env->ExceptionClear();
return false;
} methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID; return true;
} std::string JniHelper::jstring2string(jstring jstr) {
if (jstr == NULL) {
return "";
} JNIEnv *env = JniHelper::getEnv();
if (!env) {
return NULL;
} const char* chars = env->GetStringUTFChars(jstr, NULL);
std::string ret(chars);
env->ReleaseStringUTFChars(jstr, chars); return ret;
}

5,在c++端定义JNI_OnLoad接口:

 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JniHelper::setJavaVM(vm); return JNI_VERSION_1_4;
}

6,注意:

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

 
 

android NDK 实用学习(五)-c++端调用java接口的更多相关文章

  1. 基于 Android NDK 的学习之旅----- C调用Java

    许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态 ...

  2. android NDK 实用学习(一)-获取java端类及其类变量

    近期为android 端项目包装一些c++代码,故学习ndk相关知识,现总结如下: 1,java与c++类型参照图: 2,此测试中使用的java类: package com.dasea.test.co ...

  3. android NDK 实用学习(三)- java端类对象的构造及使用

    1,读此文章前我假设你已经读过: android NDK 实用学习-获取java端类及其类变量 android NDK 实用学习-java端对象成员赋值和获取对象成员值 2,java端类对象的构造: ...

  4. android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值

    1,关于java端类及接口定义请参考: android NDK 实用学习-获取java端类及其类变量 2,对传过来的参数进行赋值: 对bool类型成员进行赋值  env->SetBooleanF ...

  5. android NDK 实用学习(四)-类缓存

    1,为什么需要类缓存: 答:由于频繁的查找类及类成员变量需要很大的时间与空间开销,可参考如下文章: http://www.ibm.com/developerworks/cn/java/j-jni/ h ...

  6. 【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

    原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据 ...

  7. 基于 Android NDK 的学习之旅-----环境搭建

    工欲善其事 必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环境搭建 Android开发环境搭建不是重点,相信看此文章的 ...

  8. Android NDK开发篇(五):Java与原生代码通信(数据操作)

    尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用 ...

  9. Android NDK开发(五)--C代码回调Java代码【转】

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/41862479 在上篇博客里了解了Java层是怎样传递数据到C层代码,并且熟悉了大部 ...

随机推荐

  1. Notepad++ 右键菜单自定义配置

    问:想在右键菜单里面多加几个功能,怎么加,比如区块注释 答:其实notepad++的配置文件存放路径不在自己的软件路径,而存在于 xp:C:\Documents and Settings\Admini ...

  2. spoj 1436

    用并查集看一下是否会围成一个环  若围成环直接输出NO   当然 当 m >= n  时必然会围成环直接输出NO #include <algorithm> #include < ...

  3. CloudTest 事务监控:千呼万唤始出来

    SmartBear 数据表明,如果 Amazon 的加载时间延长 1 秒,那么一年就会减少 16 亿美元的营收.用户与网站互动的过程中,如果加载时间超过3秒,57% 的用户会流失.可见,网站的加载时间 ...

  4. mac 用 brew

    mac 下用   brew 安装插件, 有重复的不会再次安装,比xmap模式好

  5. C++对象的自销毁

    记得在学校里的时候,曾经这样写过: void MyClass::KillMe() { delete this; } 老师看到这句话的时候,眼珠子都快瞪出来了.但是运行正确啊,没什么问题. 现在想起来, ...

  6. VMware 11完全安装Mac OS X 10.10

    本文已迁移到我的个人网站 http://www.wshunli.com 文章地址: http://www.wshunli.com/2016/03/17/VMware-12安装Mac-OS-X-10-1 ...

  7. CSRF攻击[转]

    一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...

  8. 2014年最火的 21个JavaScript 框架

    下面,我们将会介绍 2014 年最火的 21 款JavaScript 框架,专为前端开发者准备的哦:)众所周知, JavaScript 框架是 JavaScript编程语言最棒的特性之一. JavaS ...

  9. PHP使用Mysql事务实例解析

    <?php //数据库连接 $conn = mysql_connect('localhost', 'root', ''); mysql_select_db('test', $conn); mys ...

  10. WinAPI——钩子函数大全

    SetWindowsHookEx 函数功能:该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件 ...