android NDK 实用学习(五)-c++端调用java接口
1,阅读此文章前请阅读前面文章,以免阅读出现障碍;
android NDK 实用学习(一)-获取java端类及其类变量
android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值
android NDK 实用学习(三)- java端类对象的构造及使用
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接口的更多相关文章
- 基于 Android NDK 的学习之旅----- C调用Java
许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态 ...
- android NDK 实用学习(一)-获取java端类及其类变量
近期为android 端项目包装一些c++代码,故学习ndk相关知识,现总结如下: 1,java与c++类型参照图: 2,此测试中使用的java类: package com.dasea.test.co ...
- android NDK 实用学习(三)- java端类对象的构造及使用
1,读此文章前我假设你已经读过: android NDK 实用学习-获取java端类及其类变量 android NDK 实用学习-java端对象成员赋值和获取对象成员值 2,java端类对象的构造: ...
- android NDK 实用学习(二)-java端对象成员赋值和获取对象成员值
1,关于java端类及接口定义请参考: android NDK 实用学习-获取java端类及其类变量 2,对传过来的参数进行赋值: 对bool类型成员进行赋值 env->SetBooleanF ...
- android NDK 实用学习(四)-类缓存
1,为什么需要类缓存: 答:由于频繁的查找类及类成员变量需要很大的时间与空间开销,可参考如下文章: http://www.ibm.com/developerworks/cn/java/j-jni/ h ...
- 【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)
原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据 ...
- 基于 Android NDK 的学习之旅-----环境搭建
工欲善其事 必先利其器 , 下面介绍下 Eclipse SDK NDK Cygwin CDT 集成开发环境的搭建. 1.Android 开发环境搭建 Android开发环境搭建不是重点,相信看此文章的 ...
- Android NDK开发篇(五):Java与原生代码通信(数据操作)
尽管说使用NDK能够提高Android程序的运行效率,可是调用起来还是略微有点麻烦.NDK能够直接使用Java的原生数据类型,而引用类型,由于Java的引用类型的实如今NDK被屏蔽了,所以在NDK使用 ...
- Android NDK开发(五)--C代码回调Java代码【转】
转载请注明出处:http://blog.csdn.net/allen315410/article/details/41862479 在上篇博客里了解了Java层是怎样传递数据到C层代码,并且熟悉了大部 ...
随机推荐
- 【转链接】Handlebars模板引擎以及浅谈模板引擎的实现原理
什么叫做“模板引擎“?我是这么理解的:就是对一些待填入数据的占位符的解析.如果你使用过Python的django框架,那你肯定是模板一点也不陌生.模板引擎就是解析模板的,把后端数据塞到前端页面模板. ...
- 写作技巧--Simile明喻
- DAO是什么技术
DAO是Data Access Object数据访问接口,数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据库资源中间. 在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应 ...
- Some projects cannot be imported because they already exist in the workspace
原文地址: Some projects cannot be imported because they already exist in the workspace - 浅尝辄止的博客 - 博客频道 ...
- MYSQL 优化建议
转自 http://coolshell.cn/articles/1846.html MYSQL 优化建议20条 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效 ...
- JavaScript DOM高级程序设计 5动态修改样式和层叠样式表2--我要坚持到底!
把样式置于DOM脚本之外 style属性 我们可以这样设置前景色之类的属性: element.style.color='red'; 也可以使用下面的代码设置背景颜色: element.style.ba ...
- NFC(8)关于新买的标签的格式化
有多种方法格式化nfc标签设备. 如搜相关的手机上应用,在应用里选择格式类型 本文是用代码手动格式 public void writeNFCTag(Tag tag) { if (tag == null ...
- Android 签名(2)签名知识要点
要点 1) 所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序 2) Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证 3) 如 ...
- 网站开发中的相对URL问题--JSP
问题描述: 入门网站开发时,我们会在相对URL问题上有疑惑.例如,在一个jsp页面中引入css外部文件, <link rel="stylesheet" hr ...
- POI2001 Gold mine(二叉排序树 黑书经典)
采矿(KOP) 金矿的老师傅年底要退休了.经理为了奖赏他的尽职尽责的工作,决定送他一块长方形地.长度为S,宽度为W.老师傅可以自己选择这块地.显然其中包含的采金点越多越好.你的任务就是计算最多能得到多 ...