1. JNI简介
java
Java Native Interface (JNI)标准是Java平台的一部分,它容许Java代码和其余语言写的代码进行交互。JNI 是本地编程接口。JVM封装了各类操做系统实际的差别性的同时,提供了JNI技术,使得开发者能够经过程序调用到操做系统相关的技术实现的库函数,从而与其余技术和系统交互,使用其余技术实现的系统的功能,同时其余技术和系统也能够用过JNI的相应原生接口调用Java应用系统内部实现的功能。c++
2. 为何要使用JNI编程
Java程序中调用C/C++开发的共享库,主要为了提升程序效率,固然程序的可移植性。好比如今公司要开发一款地图引擎,要求实现Android,IOS,JS等多平台移植,那么就要使用C++去开发地图引擎核心,去让那些平台调用,实现相应的产品。对于Android来讲,就要经过JNI来调用这个引擎核心,而IOS自己就支持C/C++。eclipse
3. JNI实例ide
(1) 编写Android项目,项目包名为:com.h1024.hellojni函数
程序入口:MainActivitythis
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.tv); TestNDK ndk = new TestNDK(); tv.setText(ndk.sayHello()+" ////1+2= "+ndk.add(1, 2)); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
封装本地接口方法:TestNDKspa
public class TestNDK { public native int add(int x,int y); public native String sayHello(); static { System.loadLibrary("TestNDK"); } }
最后运行项目,也就是将类编译字节码。
操作系统
(2) 添加本地支持,生成so库等文件code
右击工程,选择Android Tools->Add Native Support,Library Name中写上上面要加载的库文件(TestNDK),结果在本地生成jni,obj等文件夹还有一些包含库的头文件等。jni下面有TestNDK.cpp和Android.mk文件。下面是Android.mk文件的内容:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := TestNDK LOCAL_SRC_FILES := TestNDK.cpp include $(BUILD_SHARED_LIBRARY)
简单说明一下,TestNDK就是要生成的so库文件的名称,而TestNDK.cpp则是c++代码的实现,其余的不须要管,详细状况请本身查阅资料。
要想生成支持各中硬件的so库,则需本身新建一个文件,名字固定叫Application.mk,其内容是:
APP_ABI := all
运行项目(eclipse中设置ndk,自动编译),也就是编译后结果是在libs文件下生成armeabi,armeabi-v7a,mips,x86文件夹,各个文件下的都有对应的so库文件。
(3) 使用javah生成C++头文件
打开终端,cd进入工程目录,而后输入javah -classpath bin/classes -d jni com.h1024.hellojni.TestNDK,回车,在eclipse中刷新项目,就会看到jni文件里多了一个.h文件,重命名为TestNDK.h。其内容是:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_h1024_hellojni_TestNDK */ #ifndef _Included_com_h1024_hellojni_TestNDK #define _Included_com_h1024_hellojni_TestNDK #ifdef __cplusplus extern "C" { #endif /* * Class: com_h1024_hellojni_TestNDK * Method: add * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_h1024_hellojni_TestNDK_add (JNIEnv *, jobject, jint, jint); /* * Class: com_h1024_hellojni_TestNDK * Method: sayHello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_h1024_hellojni_TestNDK_sayHello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
在TestNDK.cpp文件中实现头文件里方法。
#include "TestNDK.h" #include <string.h> JNIEXPORT jint JNICALL Java_com_h1024_hellojni_TestNDK_add (JNIEnv * env, jobject clazz, jint a, jint b){ return a+b; } JNIEXPORT jstring JNICALL Java_com_h1024_hellojni_TestNDK_sayHello (JNIEnv * env, jobject clazz){ return (env)->NewStringUTF("Hello from JNI!"); }
(4) 从新运行项目,生成最终的so库。