转载请声明:原文转自:http://www.cnblogs.com/xiezie/p/5930032.html

从C/C++层调用JAVA层代码步骤:

1. 在JAVA类中创建java方法和本地方法

public class TestNdk{

    int a;//本示例中将被修改的JAVA变量
Handler handler; public TestNdk(Handler handler){
this.handler = handler;
setUp();
} public native void setUp();//本地方法 public native static int getStringFromNative();//本地方法 public int getA() {
return a;
} public native void setA(int a);//本地方法 public void notifyFiledChange(){//本示例中将被C/C++调用的JAVA方法
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putInt("a",a);
message.setData(bundle);
message.what=1;
handler.sendMessage(message);
} static {
System.loadLibrary("MyJni");//导入生成的链接库文件
} }

  2.在JNI文件夹下创建类对应的.h文件(可通过JAVAH命令生成该类的.h文件,就不赘述了),创建.cpp文件(用于编写C/C++层的代码)

  •   .h文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_x_mp4player_TestNdk */ #ifndef _Included_com_x_mp4player_TestNdk
#define _Included_com_x_mp4player_TestNdk
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_x_mp4player_TestNdk
* Method: setUp
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
(JNIEnv *, jobject); /*
* Class: com_x_mp4player_TestNdk
* Method: setA
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA
(JNIEnv *env, jobject thiz,jint i); /*
* Class: com_x_mp4player_TestNdk
* Method: getStringFromNative
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative
(JNIEnv *, jclass); #ifdef __cplusplus
}
#endif
#endif
  •   .cpp文件
#include <jni.h>
#include <com_x_mp4player_TestNdk.h> jobject m_object;
jmethodID m_mid;
jfieldID m_fid; JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative
(JNIEnv *env, jclass cls) {
return 1;
} JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
(JNIEnv *env, jobject thiz) {
jclass clazz = (*env).GetObjectClass(thiz);//获取该对象的类
m_object = (*env).NewGlobalRef(thiz);//创建对象的本地变量
m_mid =(*env).GetMethodID(clazz, "notifyFiledChange", "()V");//获取JAVA方法的ID
m_fid = (*env).GetFieldID(clazz,"a","I");//获取java变量的ID
return;
} JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA
(JNIEnv *env, jobject thiz,jint i) {
(*env).SetIntField( m_object, m_fid,i);
(*env).CallVoidMethod(m_object,m_mid);
return;
}

  

  3.调用JAVA方法需要类的对象

在C/C++层获取类的对象的方法有两种:

  • 通过JAVA层调用本地方法(如示例中的setUp()方法),在调用时,会传入对象jobject或者对象的类jclass

JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
(JNIEnv *env, jobject thiz) {
...
jclass clazz = (*env).GetObjectClass(thiz);//获取该对象的类
...
return;
}
  • 通过C/C++创建java对象

方法如下:

1.通过JAVA层的本地方法创建同类对象

步骤:

I.通过对象获取类

II.通过类获取类的构造方法的ID

III.基于方法ID和类,创建新对象

JNIEXPORT void JNICALL JAVA_nativeMethod
(JNIEnv *env, jobject thiz,jint i){
...
jclass clazz = (*env).GetObjectClass(thiz);
jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V");
jobject obj = (*env).NewObject(clazz,mid);
...
return;
}

2.通过C/C++创建不同类对象

步骤:

I.通过FindClass方法获取需要的类

II.通过类获取类的构造方法的ID

III.基于方法ID和类,创建新对象

JNIEXPORT void JNICALL JAVA_nativeMethod
(JNIEnv *env, jobject thiz,jint i){
...
jclass clazz = (*env).FindClass("com/x/test/Test");//参数为类路径
jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V");
jobject obj = (*env).NewObject(clazz,mid);
...
return;
}

3.通过C++直接创建

4.调用java方法的步骤:

    1. 获取类的方法ID
    2. 基于对象和方法id调用JAVA方法

  • 示例中是java调用本地方法setUp后,调用本地方法setA(int i),在本地方法setA(int i)中调用JAVA方法notifyFiledChange()方法

5.C/C++直接存取JAVA变量

    1. 获取对象的变量的ID
    2. 基于对象和变量id存取变量

Android JNI之C/C++层调用JAVA的更多相关文章

  1. Android JNI开发之C/C++层调用JAVA

    一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...

  2. Android NDK学习(四):C/C++层调用JAVA

    一.从C/C++层调用JAVA层代码(无参数调用) //在c代码里面调用java代码里面的方法 // java 反射 // 1 . 找到java代码的 class文件 // jclass (*Find ...

  3. 解析android framework下利用app_process来调用java写的命令及示例

    解析android framework下利用app_process来调用java写的命令及示例 在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是b ...

  4. Android JNI 由C/C++本地代码向Java层传递数据

    最近做的Android项目需要调用C代码,进行串口通信及与硬件设备通信,因此要用到JNI,其中本地代码需要向Java层返回三个参数,分别为 参数一:int型: 参数二: 通信指令,本地代码中为unsi ...

  5. 深入了解android平台的jni---本地多线程调用java代码

    一.jni调用java对象     JNI提供的功能之一是在本地代码中使用Java对象.包括:创建一个java类对象和通过函数传递一个java对象.创建一个java类对象,首先需要得到得到使用Find ...

  6. [Android] 解析android framework下利用app_process来调用java写的命令及示例

    reference to :http://bbs.9ria.com/thread-253058-1-1.html 在android SDK的framework/base/cmds目录下了,有不少目录, ...

  7. 入门: 使用JNI 从C++代码中调用Java的静态方法

    开发环境: 操作系统: (uname -a output)  Linux ubuntu 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC ...

  8. JNI NDK (AndroidStudio+CMake )实现C C++调用Java代码流程

    JNI/NDK Java调用C/C++前言  通过第三篇文章讲解在实际的开发过程中Java层调用C/C++层的处理流程.其实我们在很大的业务里也需要C/C+ +层去调用Java层,这两层之间的相互调用 ...

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

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

随机推荐

  1. C++:派生类的构造函数和析构函数

    4.2 派生类的构造函数和析构函数4.2.1 派生类构造函数和析构函数的执行顺序 通常情况下,当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数:当撤销派生类对象时,则先执行派生类 ...

  2. linux命令-shopt

    shopt命令 shopt命令用于显示和设置shell中的行为选项,通过这些选项以增强shell易用性.shopt命令若不带任何参数选项,则可以显示所有可以设置的shell操作选项. 开启与关闭 开启 ...

  3. Bean不同配置方式比较

      基于XML配置 基于注解配置 基于Java类配置 Bean定义 在XML文件中通过<bean>元素定义Bean,如:<bean class="com.bbt.UserD ...

  4. SqlServer 如何以脚本形式导出数据

    你是否遇到这样的情况,在公司导出一个数据库,回到家里导入自己的电脑里,然后发现数据库版本不匹配,这真是一个悲剧. 那么以下这个方法就可以避免这个悲剧,将数据以脚本的形式导出,这样灵活性更好. 1.选择 ...

  5. PHP JSON 操作总结

    由于JSON可以在很多种程序语言中使用,所以我们可以用来做小型数据中转,如:PHP输出JSON字符串供JavaScript使用等.在PHP中可以使用 json_decode() 由一串规范的字符串解析 ...

  6. NDK(17)让ndk支持完整C++,exception,rtti,

    C++ Support The Android platform provides a very minimal C++ runtime support library (/system/lib/li ...

  7. Image.FrameDimensionsList 属性备注

    Image.FrameDimensionsList 属性 .NET Framework 2.0   获取 GUID 的数组,这些 GUID 表示此 Image 中帧的维数. 命名空间:System.D ...

  8. ubuntu10.04开启root登陆

    半年没有用ubuntu了,以前用的是8.10,现在装了一个10.04,第一印象就是登陆窗口变了,哎,比较喜欢用root用户登录系统,不喜欢非root用户,做任何事都要来一下sudo,10.04的登陆窗 ...

  9. poj1088

    这题是dp还是dfs+记忆化?(其实好像没什么区别?) 用f[i,j]表示滑到(i,j)时之后最多能滑多远,依次穷举每一个起点(i,j)则 f[i,j]=max{f[i,j-1],f[i-1,j],f ...

  10. LA 3135 (优先队列) Argus

    将多个有序表合并成一个有序表就是多路归并问题,可用优先队列来解决. #include <cstdio> #include <queue> using namespace std ...