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. C++ 嵌套类使用(一)

    一.嵌套类 在一个类的内部定义另一个类,我们称之为嵌套类(nested class),或者嵌套类型.之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的 ...

  2. 【形式化方法:VDM++系列】3.基于VDM++的图书管理系统需求定义

    接前文:http://www.cnblogs.com/Kassadin/p/4091040.html 1.Before We Start: 在开始图书管理系统需求定义之前,需要先进行一些说明. 1.1 ...

  3. iOS开发--绘图教程

    本文是<Programming iOS5>中Drawing一章的翻译,考虑到主题完整性,翻译版本中加入了一些书中未涉及到的内容.希望本文能够对你有所帮助. 本文由海水的味道翻译整理,转载请 ...

  4. CentOS7 64位 自动分配IP地址设置

    vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 # ifcfg-后接网卡名称 配置如下,ONBOOT设置为yes HWADDR=:0C::E9 ...

  5. 安装Ubuntu双系统系列——为Firefox安装Adobe Flash Player

    使用环境:OS:Ubuntu 12.04 LTSBrowser: Firefox 12.0Adobe Flash Player: install_flash_player_11_linux.x86_6 ...

  6. 通过 PHP 判断用户的设备是否是移动设备

    <?php function isMobile() { // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($_SERVER['HTTP_X_WAP_PROF ...

  7. JavaScript DOM高级程序设计2.1创建可重用的对象--我要坚持到底!

    1.对象中包含什么 在javascript中,从函数到字符串实际上都是对象 继承 //创建一个person对象的实例 var penson={}; person.getName=function(){ ...

  8. Unicode汉字编码表

    U+  0   1  2  3  4   5  6   7   8   9   A  B  C  D  E  F  ------------------------------------------ ...

  9. How does it work in C#? - Part 3 (C# LINQ in detail)

    http://www.codeproject.com/Articles/383749/How-does-it-work-in-Csharp-Part-Csharp-LINQ-in-d

  10. 1350. Canteen(map)

    1350 这题没什么  就考一下map的用法吧 #include <iostream> #include<cstdio> #include<cstring> #in ...