一共分为2步:
1.在Java中编写要调用的静态方法和需要加载的库,并生成头文件。
2.配置gradle
3.配置Android.mk文件和application.mk文件
下面一步步的走:
首先需要在Java类中声明要调用的方法,以及要加载的库,我们在包下新建一个jniUtil类,如下所示
[plain] view plain copy
public class jniUtil {
//要加载的库,生成的库格式为:lib+库名.so
static{ System.loadLibrary("hello-jni"); }
//要调用的本地方法,在c文件中该方法名称格式为:java_包名_类名_方法名
public static native String stringFromJNI();
}
注意:在编译时该类中不能有汉字,包括注释,否则会出现编码GBK的不可映射字符错误。
接下来就是利用external Tools生成头文件.h,这里可参考点击打开链接
然后就会在main目录下生成Jni文件夹,并且包含.h文件。下面就是编写C文件,或者可以拷贝已经写好的C文件放置在该jni文件夹中.
2.配置gradle
我们这里不用gradle 去编译,而是只让他去加载已经生成的so库,改用android.mk 去编译(稍后配置android.mk)
在app的build.gradle 下的android 标签下添加:
[plain] view plain copy
sourceSets {
main {
jni.srcDirs = []//禁止gradle 自动编译,使用已经编译好的So库
jniLibs.srcDirs = ['src/main/jniLibs','libs']//指向要使用的库文件//的路径,前边的是自己项目的,后边的是第三方的so
}
}
从上面可以看出,我们生成的库是放在
src/main/jniLibs
目录下面的,那么这个是如何配置呢?还是在该gradle下面配置ndk的编译脚本,注意放在android标签外面:
[plain] view plain copy
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn CopyToJniLibs
}
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkDir = properties.getProperty('ndk.dir')
commandLine "$ndkDir/ndk-build.cmd", "NDK_PROJECT_PATH=$projectDir.absolutePath\\build", "APP_BUILD_SCRIPT=$projectDir.absolutePath\\src\\main\\jni\\Android.mk", "NDK_APPLICATION_MK=$projectDir.absolutePath\\src\\main\\jni\\Application.mk"
//你自己的mk文件目录
}
在ndkbuild完成后把生成的so文件复制到jniLibs,这里和上面配置的加载so文件路径要一致哦
[plain] view plain copy
task CopyToJniLibs(type: Copy, dependsOn: 'ndkBuild', description: 'copy the native libs to jniLibs') {
from fileTree(dir: file(buildDir.absolutePath + '/libs'), include: '**/*.so')
into file('src/main/jniLibs')
}
新建Android.mk和application.mk,这里我把Android.mk和application.mk放在jni文件夹下了,具体可以自己修改。默认生成的SO文件会在build下面的libs中,我们拷贝出来放到src/main/jniLibs下面。
3.配置Android.mk和Application.mk