【Android学习】JNI(Java Native Interface,java本地接口)编程
来源:互联网 发布:浙江大学软件学院就业 编辑:程序博客网 时间:2024/05/21 15:47
1,概念
1)JNI(Java Native Interface,java本地接口)
在Android Framework中,JNI将java层(上层)与C/C++层(底层)联系起来,让java能够找到对应的本地实现方法。
JNI提供了一系列接口,允许java类与本地语言编写的应用程序、模块、库进行交互操作。
2)场景
①注重处理速度
②硬件控制
硬件控制代码通常用C语言编写。
③已有C/C++代码的复用
已经由写好的确认安全高效的C代码。
④用C/C++调用现有jar包
我见过有人这样做,低层调用高层一般不合适,这是标准懒人做法。
但是对于效率要求不高的项目,直接调用完成度比较高的jar包可能更安全吧,我可以包容这种做法,但不推荐。
3)JNI调用过程
安装和下载Cygwin下载Android NDK
在ndk项目中JNI接口的设计
使用C/C++实现本地方法
JNI生成动态链接库.so文件
将动态链接库复制到java工程在java工程中调用运行java工程即可。
2,java和C/C++混用
首先,建立java工程从helloworld开始。Android工程一样。
1)编写java代码
用native关键字 声明本地方法,不需要实现。
本地方法可以是public、protected、private、friendly。
package com.jnitest;public class HelloJNI { //本地方法声明 native void printHello(); //加载库(dll文件,由VS生成) static{System.loadLibrary("HelloJNI");} public static void main(String[] args) { HelloJNI myJNI = new HelloJNI(); //调用本地方法(实际上是用C语言编写的JNI本地函数) myJNI.printHello(); }}
2)编译java代码
通过javac命令编译java代码,生成.class文件。
刚开始出现了错误,根据提示把java文件的Text file encoding编码方式改为GBK就可以了。
运行成功后在当前目录生成.class文件。
(Android编译后的文件放在bin/classes目录下)。
3)生成C语言头文件
用javah命令生成头文件(.h)。
-classpath <路径> 用于装入类的路径 (对于Android,后面的路径是指包”com.example.myclass”.class文件所在的根路径。对于Java,后面的路径是.class文件所在路径)-d <目录> 输出目录 (头文件输出的路径)-jni 生成 JNI样式的头文件(默认) (后面的路径是包名+类名)
生成成功,我们可在刚才指定的目录src下看到对应头文件。
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_jnitest_HelloJNI */#ifndef _Included_com_jnitest_HelloJNI#define _Included_com_jnitest_HelloJNI#ifdef __cplusplusextern "C" {#endif/* * Class: com_jnitest_HelloJNI * Method: printHello * Signature: ()V */JNIEXPORT void JNICALL Java_com_jnitest_HelloJNI_printHello (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
内容不要修改。
我们 需要看一下这个函数原型。
JNIEXPORT void JNICALL Java_com_jnitest_HelloJNI_printHello (JNIEnv *, jobject);
有2个默认的参数,JNIEnv *
是JNI接口的指针,用来调用JNI表中的各种JNI函数;参数类型jobject
也是JNI提供的Java本地类型,用来再C代码中访问Java对象,此参数中保存着调用本地方法对象的一个引用。
4)编写C代码
在.h中拿到C函数原型,写C代码(.cpp)。
/* DO NOT EDIT THIS FILE - it is machine generated */#include "HelloJNI.h"#include <stdio.h>JNIEXPORT void JNICALL Java_com_jnitest_HelloJNI_printHello(JNIEnv *, jobject) { printf("Hello World!\n"); return; }
5)生成C共享库
用VS2013,用已经写好的.h和 .cpp生成dll文件。
新建项目:
应用程序配置选择dll:
删除初始的.h和.cpp文件,导入之前写好的.h和.cpp文件。
导入后,cpp文件中有JNIEXPORT 报错:此声明没有存储类或类型说明符。
解决办法是:将 Java\jdk1.8.0_40\include\ jni.h Java\jdk1.8.0_40\include\win32\jni_md.h Java\jdk1.8.0_40\include\win32\jawt_md.h 这个3个文件拷贝到 Microsoft Visual Studio 10.0\VC\include 目录下即可。
修改项目名称为想要生成的dll文件名。
在.cpp文件右击,选择不使用预编译头。如图所示:
如果VS生成平台是32位,而java平台是64位则会报错。
Can't load IA 32-bit .dll on a AMD 64-bit platform
我们需要检查一下。
新建并选择x64。
项目名称右击生成。在 debug目录可以看到生成的dll文件。
为了方便 日后修改,我们不需要移动dll文件,这样 以后VS平台开发生成后可以直接再java平台使用。
6)运行java程序
接下来就是把刚才的dll文件导入java项目中。
双击Native library location:…,选择dll路径。
运行java,成功。我们可以看到控制台输出了Hello World!
3,应用
1)Android
再Android系统 中,有大量代码使用了JNI函数,这些代码存在于Android源码的相关目录中:
framworks\base\core\jni
framworks\base\services\jni
framworks\base\media\jni
有时间翻阅一下源码。
2)eclipse-failed to load the JNI shared library问题
问题:
很久没有用eclipse,刚才打开,提示:failed to load the jni shared library。这个问题一般是eclipse和JDK位数不一样。
解决方案:
1,在cmd中输入【Java -version】
在这里,画线部分是Client VM表示是32位的jdk。若是64-bit Server,表示64位jdk。
2,打开eclipse安装目录
记事本方式打开eclipse.ini。我用sublime打开的。如下图。划红线处,是win32.x86表示32位。win32.x86_64,是根据你电脑的环境来安装,我电脑是64位机,所以eclipse是64位。所以jdk和eclipse版本不同。
- 【Android学习】JNI(Java Native Interface,java本地接口)编程
- Java本地接口(Java Native Interface (JNI))
- JNI(Java Native Interface,) java本地接口
- Android中Java的本地接口调用(JNI:Java native interface)
- Java本地接口(Java Native Interface (JNI))概述
- android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )
- Android JNI(java native interface) 学习笔记
- Android JNI(java native interface) 学习笔记
- JNI(java native interface , java本地调用)
- java 本地接口(java native interface)
- JNI(Java Native Interface)
- JNI(Java Native Interface)
- JNI (Java Native Interface) 编程示例
- JNI:Java Native Interface
- JNI(java native interface)
- JNI - Java Native Interface
- JNI:Java Native Interface
- Java Native Interface (JNI)
- SCUT Training 20170920 Problem O
- CentOS7使用firewalld打开关闭防火墙与端口
- Tomcat的总体架构
- js利用HTML5的拖拽API做拖拽的流程图
- 获取Button上的字
- 【Android学习】JNI(Java Native Interface,java本地接口)编程
- Python3 网络编程
- ES6
- AC-Apple
- mysql 查看数据库表、字段信息
- 【MR】MapReduce 常见的排序
- 怎么形象的理解三次握手与四次挥手
- log4j.properties配置详解与实例
- Cesium应用篇:3控件(6) FullScreen/ VR / Home