什么是JNI:
JNI: java本地开发接口, JNI 是一个协议 ,这个协议用来沟通java代码和外部的本地代码(c/c++). 通过这个协议,java代码就可以调用外部的c/c++代码 ,外部的c/c++代码也可以调用java代码。
为什么用JNI:
JNI扩展了java 虚拟机的能力, 驱动开发 (wifi-hotspot) ,2.3 无线热点共享;
Native code效率高,数学运算,实时渲染的游戏上,音视频处理 (极品飞车,opengl,ffmpeg);
复用代码 (文件压缩,人脸识别…);
特殊的业务场景;
怎么用JNI:
1.C/C++语言;
2.掌握java jni流程;
3.NDK (native develop kits );
搭建ndk开发环境:
1.为eclipse增加c和c++的开发插件
点击:Help中的install new software,选择 Helios- http://download.eclipse.org/release/helios
等待展开,选择Programing language,选择c/c++ 开发工具,一路next下去。 同意licenses,安装成功会提示是不是确认重启eclipse,重启就完成安装。
2,安装cygwin
Ndk需要运行在linux环境下,cygwin是windows下模拟linux的一个工具。
Cygwin是一个程序,支持很多插件。双击安装。把需要下载的东西下载好,选择install from local directory。
安装完毕后 ,桌面会出现一个快捷图标,现在打开 cygwin,首先程序会初始化,敲入命令:
Make –v
显示出来 GNU Make 的版本 ,说明我们的cygwin模拟的linux编译环境 模拟成功了.下面去安装android ndk,下载之后直接解压到某个目录下 ,如图:
配置NDK的 cygwin环境变量
为了方便直接在命令行里面使用ndk-build需要给cygwin的环境变量里面添加ndk的目录,目录/etc/profile/.
NDK HelloWorld:
2.JAVA代码中写声明native 方法
<span style="font-size:12px;"> /* A native method that is implemented by the
* 'hello-jni' native library, which is packaged
* with this application.
*/
public native String stringFromJNI();</span>
<span style="font-size:12px;">#include <string.h>
#include <jni.h>
/* This is a trivial JNI example where we use a native method
* to return a new VM String. See the corresponding Java source
* file located at:
*
* apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
*/
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
</span>
4.编写Android.mk文件
<span style="font-size:12px;">LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
</span>
5.Ndk编译生成动态库
6.Java代码load 动态库.调用native代码
<span style="font-size:12px;"> static {
System.loadLibrary("hello-jni");
}</span>
注意:
Android.mk详细介绍
LOCAL_PATH:=$(call my-dir)
LOCAL_PATH是定义源文件在哪个目录用的.
my-dir 是个定义的宏方法, $(call my-dir)就是调用这个叫 my-dir的宏方法,这个方法返回值就是
Android.mk文件所在的目录
include $(CLEAR_VARS)
CLEAR_BARS 变量是build system里面的一个变量
这个变量指向了所有的类似 LOCAL_XXX的变量,
执行完这一句话, 这个编译系统就把 所有的类似
LOCAL_MODULE,_SRC_FILELOCALS,LOCAL_STATIC_LIBRARIES,...这样的变量都清除掉
但是不会清除掉 LOCAL_PATH
LOCAL_MODULE 就是你要生成的库的名字,名字要是唯一的这个.不能有空格.
编译后系统会自动在前面加上lib的头, 比如说我们的Hello 就编译成了libHello.so
还有个特点就是如果你起名叫libHello 编译后ndk就不会给你的module名字前加上lib了
但是你最后调用的时候 还是调用Hello这个库
LOCAL_SRC_FILES = :Hello.c
这个是指定你要编译哪些文件
不需要指定头文件 ,引用哪些依赖, 因为编译器会自动找到这些依赖 自动编译
include $(BUILD_SHARED_LIBRARY) BUILD_STATIC_LIBRARY.so
编译后生成的库的类型,如果是静态库.a 配置include $(BUILD_STATIC_LIBRARY)
别的参数
LOCAL_CPP_EXTENSION := cc //指定c++文件的扩展名
LOCAL_MODULE := ndkfoo
LOCAL_SRC_FILES := ndkfoo.cc
LOCAL_LDLIBS += -llog -lvmsagent -lmpnet -lmpxml -lH264Android
//指定需要加载一些别的什么库.
重新审视这个程序
2.JAVA代码中写声明native 方法 public native String helloFromJNI();
3.用javah工具生成头文件
4. 创建jni目录,引入头文件,根据头文件实现c代码
5.编写Android.mk文件
6.Ndk编译生成动态库
7.Java代码load 动态库.调用native代码