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层代码,并且熟悉了大部 ...
随机推荐
- Win2003+iis6部署MVC4网站的方法
1.服务器上安装SP2 和 IIS6 2.安装.Net Framework3.5 SP1(完整安装包,包含2.0 2.0SP1,237MB那个安装包) 3.安装.Net Framework4.0 4. ...
- CentOS 5: Make Command not Found
在centos 5下安装软件遇到的问题,google了一圈,是因为系统没有安装编译器,那安装就是了,嘿嘿. 解决办法,在SSH下输入下面的命令 yum -y install gcc automake ...
- 用std::thread替换实现boost::thread_group
thread_group是boost库中的线程池类,内部使用的是boost::thread. 随着C++ 11标准的制定和各大编译器的新版本的推出(其实主要是VS2012的推出啦……),本着能用标准库 ...
- POJ1265Area
http://poj.org/problem?id=1265 题意 : 给你一个点阵,上边有很多点连成的多边形,让你求多边形内部的点和边界上的点以及多边形的面积,要注意他每次给出的点并不是点的横纵坐标 ...
- HDU4548+素数
简单题. /* */ #include<stdio.h> #include<string.h> #include<stdlib.h> #include<alg ...
- Qt之启动外部程序(调用cmd.exe ping putty winscp 管道等等,比较牛叉)
http://blog.csdn.net/u011012932/article/details/50478833
- Android:@id和@+id
@id代表引用已有的id,而@+id是新增加一个id 如果使用@+id/name形式,当R.java中存在名为name变量时,则该组件会使用该变量的值作为标识.如果不存在该变量,则添加一个新的变量,并 ...
- MyBatis的CRUD操作
MyBatis的两个主要配置文件 mytatis.xml:放在src目录下,常见的配置如下 <?xml version="1.0" encoding="UTF-8& ...
- PC寄存器的真实状态
因为预取指令的关系,PC寄存器永远比当前的寄存器多两个指令,ARM模式为大8,Thumb模式为大2,这针对的是32bit的ARMv7的指令集 In ARM state, the value of th ...
- 中文编码之GB2312,Big5,GBK简介
汉字编码中现在主要用到的有三类,包括GBK,GB2312和Big5. 1.GB2312 又称国标码,由国家标准总局发布,1981年5月1日实施,通行于大陆.新加坡等地也使用此编码.它是一个简化字的编码 ...