JNI(Java Native Interface),提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。在android开发时,调用一些已有的c或者c++写好的库,以及在某些追求性能和安全性的情况下,我们就得使用jni编程技术去实现。这里带大家简单的走一遍jni调用过程,完成一个简单的hello jni项目。
本项目在Mac环境下,Android Studio中搭建,且要事先配置好NDK(这里主要介绍jni项目搭建,就不啰嗦ndk的配置过程了)。
步骤如下:
步骤一:新建项目配置ndk,即在local.properties加入ndk.dir=<你的ndk安装路径>,且在gradle.properties中加入android.useDeprecatedNdk=true。
步骤二:在项目中新建class类,内部声明native方法。
如图,getNativeString便是我们要调用的native方法,而静态代码块中的System.loadLibrary(“jnitest”)是用来引入我们将要生存的jni库,jnitest只是一个引入名,这里可以按照自己项目定义。
步骤三:build project得到中间文件,即.class文件。class文件在as工程的路径:../app/build/intermediates/classes/debug
步骤四:命令进入class文件路径,然后执行javah命令生成对应的.h都文件:
xxxxx\debug> javah -jni com.github.liujianwj.jnisimplydemo.JniUtils
然后将在当前目录下生成的.h文件,剪切到项目新建目录src/main/jni文件下,在此目录下新建c文件,在c文件写具体实现代码。本项目中只是简单的输出一个字符串
#include "com_github_liujianwj_jnisimplydemo_JniUtils.h"
/*
* Class: com_github_liujianwj_jnisimplydemo_JniUtils
* Method: getNativeString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_github_liujianwj_jnisimplydemo_JniUtils_getNativeString
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
}
步骤五:在jni文件下新建Android.mk文件,在当前目录下执行ndk-build APP-ABI = “armeabi armeabi-v7a x86 arm64-v8a”,生成so文件。Android.mk内容为:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := jnitest
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := com_github_liujianwj_jnisimplydemo_JniUtils.c
include $(BUILD_SHARED_LIBRARY)
LOCAL_MODULE为步骤一中定义的引入名,第一步中的静态代码块也可最后添加,只要保证LOCAL_MODULE与System.loadLibrary(String libName)中的libName一致就行。LOCAL_SRC_FILES为.c文件名。如下为生成的so文件:
最后记得在build.gradle 中指定jnilibs路径 ,添加代码:sourceSet.main{ jinLibs.srcDir ‘< 存放so文件的libs路径>’}
然后就可以在我们的项目中调用getNativeString()方法获取jni中输出的字符串了
TextView textView = (TextView) findViewById(R.id.text);
JniUtils jniUtils = new JniUtils();
textView.setText(jniUtils.getNativeString());
运行下,效果图为