今天练习了用studio编译c生成.so文件。
一、首先是配置NDK(以下是以我自己的路径为例)
二、环境的搭建
设置ndk路径
成功之后我们可以在local.properties文件中看到:
之后还要在gradle.properties文件中添加一行代码:android.useDeprecateNdk=true(否则会报错)
三、JNI开发
环境都搭建好就可以进行java代码和C代码的编写了。
首先先建一个java类JNIUtlils.java(我起名字的时候多了个l,忽略这个细节~)
注意:这个类里面调用C的方法必须要用native声明,而且方法名也要和C中的一样;
System.loadLibrary("")引号中的是你要生成库的名字,不加后缀.so
之后重新make project
在D:\Studio\Demo\JniTest\app\build\intermediates\classes\debug\com\xiezhong\jniTest中看到JNIUtlils.class
接下来生成.h头文件。在studio的左下方可以找到Terminal,点开它
之后进入到build\intermediates\classes\debug目录中去,执行javah -classpath . -jni com.xiezhong.jniTest.JNIUtlils命令(此处填你自己刚刚生成的class路径)
执行后在debug目录下就会生成一个.h文件
在main中创建一个jni文件夹
将上面debug目录下新生成的.h文件剪切到jni文件夹中,再在jni里创建一个.c文件
(我的文件为com_xiezhong_jniTest_JNIUtlils.c)
编辑内容如下:
#include "com_xiezhong_jniTest_JNIUtlils.h"
/**
* 上边的引用标签一定是.h的文件名加后缀,方法名一定要和.h文件中的方法名称一样
*/
JNIEXPORT jstring JNICALL Java_com_xiezhong_jniTest_JNIUtlils_getString
(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "这是我测试的jni");
}
.c和.h文件都完成了,接下来在jni中创建Android.mk和Application.mk文件
首先Android.mk的内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := huazict
LOCAL_SRC_FILES := com_xiezhong_jniTest_JNIUtlils.c
include $(BUILD_SHARED_LIBRARY)
注意:LOCAL_MODULE是要编译的库的名字,编译器会自动加上lib的前缀和.so的后缀
LOCAL_SRC_FILES是要编译的C/C++文件
Application.mk内容:
APP_ABI := all
这些都完成后我们开始配置gradle:
注意:红色横线标记的一定要加上,因为jni每次运行都会在build\intermediates\ndk中自动编译生成一个Android.mk文件,这样我们之前在jni中手动编译的Android.mk就没有作用了,然后就会报如下错误:
Warning:Deprecated NDK integration enabled by useDeprecatedNdk flag in gradle.properties will be removed from Android Gradle plugin soon.
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: Error while executing 'D:\ndk\android-ndk-r9d\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\Android.mk APP_PLATFORM=android-25 NDK_OUT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi-v7a,armeabi,x86}
所以jni.srcDirs = [ ]一定要加上,这样就不会自动编译了,用的是我们自己的mk文件。
最后我们在Terminal中进入到main目录下执行ndk-build命令:
这样我们的.so文件就生成好了:
把libs中的.so都复制到外面的jniLibs文件夹中:
现在我们可以运行我们的程序了,结果如下图:
希望对大家有所帮助~~