JNI和NDK
JNI: Java Native Interface Java调用本地代码接口
NDK : Native development Kit 安卓提供的本地开发包,用于编译成.so文件 (linux平台的库文件)
ABI :Application binary interface 应用程序二进制接口 ,.os文件以lib开始,以abi结尾,以便各自Cpu调用对应的so文件
一、JNI流程
1、新建本地方法类,以native关键字标识,例如
public class JniTest { public native String getText(); public native Void setText(String text); }
2、使用javac生成class文件,然后使用javah生成.h文件(此处主要,由于.h文件中的函数名需要包名和方法名,所以javah的参数必须是完整的带包名的 例如 javah com.test.jni.JniTest)
3、新建.c或者.cpp文件实现.h文件的函数
4、然后使用gcc 编译成so文件,需要linux环境。Android开发者可用NDK包中的ndk-build命令代替
二、NDK流程
1、新建本地方法类,以native关键字标识,例如
public class JniTest { public native String getText(); public native Void setText(String text); }
2、使用javac生成class文件,然后使用javah生成.h文件(此处主要,由于.h文件中的函数名需要包名和方法名,所以javah的参数必须是完整的带包名的 例如 javah com.test.jni.JniTest)
3、在main文件夹下即和java文件夹同级新建jni文件夹,将.h文件放入其中,在该目录下新建.c和Android.mk和Application.mk文件
.c文件如下:
#include <jni.h> #include <com_lihui_test_jni_JniTest.h> JNIEXPORT jstring JNICALL Java_com_lihui_test_jni_JniTest_getText(JNIEnv *env, jobject instance) { // TODO return (*env)->NewStringUTF(env, "hello jni"); } JNIEXPORT jobject JNICALL Java_com_lihui_test_jni_JniTest_setText(JNIEnv *env, jobject instance, jstring text_) { const char *text = (*env)->GetStringUTFChars(env, text_, 0); // TODO (*env)->ReleaseStringUTFChars(env, text_, text); }
Android.mk文件如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni //类库名称 LOCAL_SRC_FILES := jnitest.c //编译的文件 include $(BUILD_SHARED_LIBRARY) //shared可用如apk包
Application下
APP_ABI := all //全部类型
4、使用ndk-build编译成so文件 主要需要配置环境变量 指定工程目录 例如 ndk-build NDK_PROJECT_PATH=D:\Android\WorkSpace\JNI\app\src\main 保证jni文件夹在此目录下,然后就会生成libs,obj等文件夹,包含了so文件
5、在main下新建jniLibs文件夹,将libs下的so文件拷入
6、然后修改本地方法类 调用本地方法类 如下
public class JniTest { static { System.loadLibrary("hello-jni"); } public native String getText(); public native Void setText(String text); } public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.tv); JniTest jniTest = new JniTest(); tv.setText(jniTest.getText()); } }