上篇文章主要说了使用android studio写jni的 build.gradle配置,接下来继续说jni的module配置。
一、jni基本配置
1、右键module名称,new->folder->jni folder.默认会在main目录下创建jni目录。
2、网上有许多都是使用java名称生成jni文件,其实也手写也可以随意些一个名称即可,包含.h c/c++两个文件。
3、在jni目录下创建Android.mk与Application.mk文件
Android.mk有比较多的语法,也是编译jni的依据是重点也是难点,下面我们会详细讲述。
Application.mk语法比较少,常用的有APP_ABI:=x86 x86_64 armeabi armeabi-v7a 根据需要填写平台类型。
下面就可以编译了,编译后的库会存在于build.gradle中配置的目录下,如下所示:
sourceSets { main { jni.srcDirs = [] // disable automatic ndk-build call jniLibs.srcDirs = ['src/main/libs'] } }
二、jni文件与java文件链接
jni与java链接有两种方式,静态链接与动态链接。
静态链接:
1、jni方法类型:JNIEXPORT <方法类型> JNICALL com_xx(包名)_(java类名)_(方法名)(JNIEnv *env, jobject jclazz,...(参数))
2、java对应类执行loadlibrary。
动态链接:
1、jni方法类型 JNIEXPORT <方法类型> JNICALL 方法名(JNIEnv *env, jobject jclazz,...(参数))
2、jni写JNI_OnLoad函数
const char* aprServicePath = "com/example/sun/Test";
jint JNI_OnLoad(JavaVM* aVm, void* aReserved) { JNIEnv* env; ALOGD ("JNI_OnLoad"); if (aVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { ALOGE ("Failed to get JNI_1_6 environment"); return -1; } jclass activityClass; if(PACKAGE_IS_SERVICE) activityClass = env->FindClass(aprServicePath); else activityClass = env->FindClass(activityClassPath); if (!activityClass) { ALOGE("failed to get %s class reference", activityClassPath); return -1; } env->RegisterNatives(activityClass, methodTable, sizeof(methodTable) / sizeof(methodTable[0])); ALOGD ("JNI_OnLoad end"); return JNI_VERSION_1_6; }static JNINativeMethod methodTable[] = { {"test","(Z)Z", (void *) jniTest}}Android.mk有比较繁琐的语法,建议读者买本书当做字典来查找,这里只简单的介绍,有机会会单独开一章去写。3、java对应类执行loadlibrary。可见静态注册是系统根据包名类名去一一链接的,动态注册是自己将jni方法与java类方法一一对应起来的。这样一个jni就与java链接起来了。三、Android.mk书写与语法1、jni引用第三方动态库,需要预编译,在Android.mk中是这样写的。include $(CLEAR_VARS) //清除所有的变量初值 LOCAL_MODULE := libtest1 //预编译后动态库名称 LOCAL_SRC_FILES := lib/libtest1.so //动态库绝对路径 include $(PREBUILT_SHARED_LIBRARY) //编译后类型2、jni引用第三方编译自己的动态库include $(CLEAR_VARS) LOCAL_LDFLAGS := -llog -g //使用安卓logcat LOCAL_MODULE := test2 //编译目标名称 LOCAL_SHARED_LIBRARIES = libtest1 //编译依赖第三方库 LOCAL_SRC_FILES := core/test2.cpp core/other.cpp //编译源文件 LOCAL_PROGUARD_ENABLED:= disabled //不使用混淆工具混淆 include $(BUILD_SHARED_LIBRARY) //编译后类型这样一个依赖第三方库的jni Android.mk文件就写完了,可以应付大部分jni工程。