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层代码,并且熟悉了大部 ...
随机推荐
- POJ2528+线段树
见代码. /* 线段树+Lazy 题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度. 现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW. 后贴的海 ...
- 【形式化方法:VDM++系列】3.基于VDM++的图书管理系统需求定义
接前文:http://www.cnblogs.com/Kassadin/p/4091040.html 1.Before We Start: 在开始图书管理系统需求定义之前,需要先进行一些说明. 1.1 ...
- hdu 3929 Big Coefficients 容斥原理
看懂题目,很容易想到容斥原理. 刚开始我用的是二进制表示法实现容斥原理,但是一直超时.后来改为dfs就过了…… 代码如下: #include<iostream> #include<s ...
- net.sf.json.JSONException: Object is null
出现这个错误的原因是net.sf.json.JSONArray或JSONObject转换时,对象内包含另一个对象,而该被包含的对象为NULL,所以抛出异常. 补充: 最可恨的是,明明转换的时候已经成功 ...
- Android 设置EditText光标位置
Android中有很多可编辑的弹出框,其中有些是让我们来修改其中的字符,这时光标位置定位在哪里呢? 刚刚解了一个bug是关于这个光标的位置的,似乎Android原生中这种情况是把光标定位到字符串的最前 ...
- Android view的requestLayout()
public void requestLayout () Since: API Level 1 Call this when something has changed which has inval ...
- python numpy笔记:给matlab使用者
利用Numpy,python可以进行有效的科学计算.本文给过去常用matlab,现在正学习Numpy的人. 在进行矩阵运算等操作时,使用array还是matrix?? 简短的回答,更多的时候使用arr ...
- 【Lucene3.6.2入门系列】第04节_中文分词器
package com.jadyer.lucene; import java.io.IOException; import java.io.StringReader; import org.apach ...
- poj 2031 Building a Space Station(prime )
这个题要交c++, 因为prime的返回值错了,改了一会 题目:http://poj.org/problem?id=2031 题意:就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能 ...
- poj 2049 Finding Nemo(优先队列+bfs)
题目:http://poj.org/problem?id=2049 题意: 有一个迷宫,在迷宫中有墙与门 有m道墙,每一道墙表示为(x,y,d,t)x,y表示墙的起始坐标d为0即向右t个单位,都是墙d ...