转载请声明:原文转自: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. CentOS 7.0安装Nvidia驱动

    entOS 7.0 Nvidia显卡安装步骤: 1 在英伟达官网下载相应驱动 搜索出相应的驱动后,不要直接点,而是右健,Save Link as... 否则,会出现下载半天没动静的情况. 存放的路径上 ...

  2. NSRange

    int main(int argc, const char * argv[]) {    @autoreleasepool {        // insert code here...       ...

  3. Netstat 命令

    简介 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Member ...

  4. Android zxing连续扫描

    initCamera(); if (mHandler != null) mHandler.restartPreviewAndDecode(); 在扫描完毕后执行这3句即可. 说明: 1.扫描处理方法为 ...

  5. 分享一个免费SSL证书申请网站,给网站开启https协议 | 张戈博客

    这些天,由于公司的业务需求,接触到了ssl证书和https协议.博客前几篇文章也分享了在WEB服务器上安装SSL证书,为网站开启https协议的教程,感兴趣的童鞋可以前往查看相关文章: <Lin ...

  6. [转载]浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  7. php有些系统会报错或提示 Cannot modify header information - headers already sent by

    Warning: Cannot modify header information - headers already sent by (output started at /home/test/do ...

  8. POJ 1577 Falling Leaves

    题意:给出一些字符串,从上到下的建树,输出其前序遍历 像前面那一题一样,先建树,然后再递归前序遍历 不过想像上一题那样用数组建树,建树和上题一样的办法,可是应该怎么输出前序遍历呢= = 还是看的题解= ...

  9. ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking

    #!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-targetfs-nfs.sh hacking # 说明: # 本文主要对TI的s ...

  10. cgroup的测试数据

    [root@xxxx /cgroup/memory/rule3021]#cat memory.limit_in_bytes503316480   480M [root@xxxx /cgroup/mem ...