javah命令配置
android studio中class文件的目录在app\build\intermediates\javac\debug\classes里面
例如:D:\test2\app\build\intermediates\javac\debug\classes\com\example\myapplication
我们在使用javah生成class的头文件之前,首先要保证java类已经被编译成了class文件,然后执行javah的命令
例如:javah -classpath d:/ -d d:/Test -jni Test
-classpath 是指从中加载类的路径,需要注意在命令的最后需要拼上class的名字,否则会找不到class文件
-d 是指输出目录,我们通过javah生成的头文件会输出到指定目录
-jni 是指生成 JNI 样式的标头文件 (默认值),其实这个-jni写不写无所谓的,因为-jni就是默认值
android studio配置javah快捷命令参数:
Program: $JDKPath$\bin\javah.exe
Arguments:
-classpath
D:\test2\app\build\intermediates\javac\debug\classes
-jni
-d
$SourcepathEntry$\..\jni
$FileClass$
Working directory: $ProjectFileDir$
注:
$SourcepathEntry$的路径是:D:\test2\app\src\main\java,然后这个..\取的是当前路径的上级目录,这样的话jni目录就可以和java目录平级方便我们查看。
后续我们的jni目录会存放Android.mk Application.mk 以及hello.c文件,这个生成的头文件需要和他们在同一个目录,否则会报找不到头文件的错误
$ProjectFileDir$的路径是:D:\test2,这里取的就是项目的根目录
注:我们使用android studio生成对应的.h头文件的时候,需要在我们对应的java类上面,例如NdkTest这个java类右键,使用javah命令生成头文件,具体如下图:
ndk-build命令配置
Program: D:\Android\Sdk\ndk-bundle\ndk-build.cmd
Arguments: (这里可以不配置,默认会在目录D:\test2\app\src\main\libs生成对应的so文件)
Working directory: $ProjectFileDir$\app\src\main
注:在jni这个目录下有四个文件,分别是Adnroid.mk, Apllication.mk, com_example_myapplication_NdkTest.h, hello.c,
当我们执行ndk-build命令的时候,需要右键jni这个目录,然后执行ndk-build,然后系统会系统帮我们生成对应的.so库文件,具体如下图:
生成的.so相关文件如下图:
jni文件目录构成
Android.mk文件
LOCAL_PATH := $(call my-dir) #此变量表示源文件在开发树中的位置。在上述命令中,构建系统提供的宏函数 my-dir
将返回当前目录(Android.mk
文件本身所在的目录)的路径。
include $(CLEAR_VARS) #CLEAR_VARS
变量指向一个特殊的 GNU Makefile,后者会为您清除许多 LOCAL_XXX
变量
LOCAL_MODULE := myjni #LOCAL_MODULE
变量存储您要构建的模块的名称
LOCAL_SRC_FILES =: Hello.c #LOCAL_SRC_FILES
变量必须包含要构建到模块中的 C 和/或 C++ 源文件列表
include $(BUILD_SHARED_LIBRARY) #BUILD_SHARED_LIBRARY
变量指向一个 GNU Makefile 脚本,该脚本会收集您自最近 include
以来在 LOCAL_XXX
变量中定义的所有信息。此脚本确定要构建的内容以及构建方式。
Application.mk文件
APP_MODULES := myjni #要构建的模块的显式列表。此列表的元素是模块在 Android.mk 文件的 LOCAL_MODULE
中显示的名称。
APP_ABI := all #默认情况下,NDK 构建系统会为所有非弃用 ABI 生成代码。all表示所有支持的 ABI(默认)
Hello.c文件
#include <string.h>
#include <jni.h>
#include "com_example_myapplication_NdkTest.h"
JNIEXPORT jstring JNICALL Java_com_example_myapplication_NdkTest_hello(JNIEnv *env, jobject obj)
{
return (*env)->NewStringUTF(env, "i am jni call!");
}
build.gradle文件配置
ndk {
moduleName "myjni" //声明使用jni的类库名字
}
sourceSets {
main {
jniLibs.srcDirs = ['src/main/libs','libs'] //声明安卓程序运行时候读取so库文件的位置
}
}
安卓调用示例:
jniText = findViewById(R.id.jni_text)
jniText!!.setText(NdkTest().hello())
配置完成之后,右键jni执行ndk-build命令,会在libs目录下生成编译之后的xxx.so文件,这个so文件就是安卓可以直接使用的so库文件。