以前开发Android或Java基本上使用Java语言,最近看面试题老是遇到Jni相关的东西,以前碰到这个问题总觉得用不到,就没有接触,但是不懂得东西慢慢的就会成为前进路上的绊脚石,于是在这几天受尽Jni各种配置的折磨后,终于把他给征服了。
先来说说JNI技术,Jni是Java和其他语言之间的一个桥梁,实现了Java和其他语言之间的调用。其实主要使用的还是Java和C/C++之间的调用。
用Jni的优点:1、在程序对时间敏感和对性能要求特别高时,有必要使用底层语言来实现。2、代码的保护,由于java层代码很容易被反编译,而C/C++库反汇难度较大。3、 在Jni中有利于调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
而NDK(Native Development Kit),是Android运用Jni技术进行本地开发的工具集。
JNI开发步骤:1、在Java类中声明native方法,并编译成.class文件
2、用javah命令,将上面的class文件生成头文件
3、用其他语言实现头文件中的函数,并生成动态链接库(在Windows系统中是.dll文件,在Linux中是.so文件)
4、在Java中加载相应的动态链接库
首先下面是在Windows系统上实现的一个Java代码调用C方法的函数:
第一步:声明native方法
package com.liushuai;
public class Hello {
public native void sayHello();
public static void main(String[] args) {
new Hello().sayHello();
}
}
编译成.class文件,这里就不截图了,我是在Eclipse IDE下编译的。
第二步:用javah命令,将上面的class文件生成头文件
这样就会编译出一个.h文件。
第三部:用其他语言实现头文件中的函数,并生成动态链接库(在Windows系统中是.dll文件,在Linux中是.so文件)
然后建立一个C++工程,我用的是VC++6.0,在VC++中建立一个Win32 Dynamic-Link Library工程,然后将你的那个头文件复制进去,打开你会发现里面有一个函数声明。
在工程中新建一个源文件来实现这个函数,
Hello.cpp
#include "com_liushuai_Hello.h"
#include<stdio.h>
/*
* Class: com_liushuai_Hello
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_liushuai_Hello_sayHello
(JNIEnv *, jobject){
printf("Hello Jni");
}
这个时候要注意这里面引用的jni头文件还没有加进来,我使用的方法是在将jin.h和jni_md.h复制到工程里。这两个文件在jdk目录下的include中能够找到,还要注意将引用头文件那里的<>改为”“。
下面编译链接,然后再 组建->组建dll就能生成一个.dll的链接文件。
这个时候你的程序还不能找到这个dll文件,你要把他加到环境变量里面,可以把你的dll文件的路径加到环境变量里面,还可以把dll文件加到一个环境变量的路径里面。
第四部:在Java中加载相应的动态链接库
在Java类中加入加载的语句:
package com.liushuai;
public class Hello {
//这句是加载链接文件,HelloJni是dll的文件名
static {
System.loadLibrary("HelloJni");
}
public native void sayHello();
public static void main(String[] args) {
new Hello().sayHello();
}
}
运行Java程序,看看输出结果:
下一篇再说说Android的 NDK开发,有什么写的不对的地方,欢迎拍砖指正。