转载请声明:原文转自: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. Linux之vi/vim命令

    vi命令是linux中必不可少的一个编辑器工具.那么vi与vim又有什么区别呢,可以简单理解为vim是vi的升级版.在编辑一个文本时,vi不会显示颜色,而vim会显示颜色.显示颜色更易于用户进行编辑, ...

  2. 40. Combination Sum II

    题目: Given a collection of candidate numbers (C) and a target number (T), find all unique combination ...

  3. POJ2891——Strange Way to Express Integers(模线性方程组)

    Strange Way to Express Integers DescriptionElina is reading a book written by Rujia Liu, which intro ...

  4. [Linux 命令]df -h

    查看目前磁盘空间和使用情况 以更易读的方式显示

  5. Android如何获取开机启动项列表

    static final String BOOT_START_PERMISSION = "android.permission.RECEIVE_BOOT_COMPLETED"; p ...

  6. 转AOP 介绍

    来自:http://blog.csdn.net/a906998248/article/details/7514969 这篇也不错,详细介绍了CGLIP http://blog.jobbole.com/ ...

  7. 完美配置Tomcat的HTTPS

    Tomcat配置HTTPS的文章到处都有,过程也比较简单,随后文中会转一段过来. 但对于启用APR情况下报异常“java.lang.Exception: Connector attribute SSL ...

  8. IOS数据类型

    id – 动态对象类型.动态类型和静态类型对象的否定词汇为 nil. Class – 动态类的类型.它的否定词汇为 Nil.SEL – 选择器的数据类型(typedef):这种数据类型代表运行时的一种 ...

  9. $.post()

    定义和用法 post() 方法通过 HTTP POST 请求从服务器载入数据. jQuery.post(url,data,success(data, textStatus, jqXHR),dataTy ...

  10. 迷宫问题(bfs的应用)

    问题描述: 定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: int maze[5][5] = { 0, 1, 0, 0, 0, 0, ...