不靠谱的朱先生又来了,今天是周五,我又出现了!好了,不为自己多解释,上周没发文章,其实我写了,只是没有发出来而已……机智ovo。
上周写的文章是关于GreenDao全面解析,其实当时是想写一个关于数据库的系列文章,后来一共就写了两篇,SQlite全面解析和GreenDao全面解析。至于原先计划的编写LitePal, Realm,wcdb的介绍文章可能要推后了,因为现在计划是先把FFmpeg这一系列的文章给写出来,毕竟我的主修的是音视频开发!在学习FFmpeg的过程中,我想以这篇文章作为这个系列的第一篇!ok,让我们一块学习如何在Android中编辑调用C语言及如何编译成so库供其他项目调用,以及最后如何使用别人项目中so库文件?
大家在使用学习使用so库的时候遇到什么问题,欢迎在我的公众号aserbao给我留言,无偿服务!同时,欢迎大家来加入微信群二维码讨论群,一起讨论Android开发技术!群二维码定时在我公众号更新!
好了,在学习这篇文章之前,请查看下如下几个问题(本文主要解决的问题列表):
- 你知道Android 如何调用C代码?
- 你知道如何生成so文件?
- 你知道如何同时生成多个so文件?
- 你知道如何将多个so文件合并成一个so文件?
- 你知道如何调用so库文件?
- 你知道如何查看so中的类名,路径和方法名?
好了,看了上面问题无论你知道几个,我都建议你看下这篇文章,因为毕竟写了那么久,麻烦帮我看下有没有写错的地方,最后无论好坏,帮忙点评下,最后点个赞就再好不过了!
最后,温馨提示:未成年人(未满18周岁),本文内容可能会引起你的不适,请在家长的陪伴下进行观看!
文章目录
编译环境
- Android Studio 3.0.1
- macOS Mojava 10.14
- android-ndk-r16b-darwin-x86_64.zip
如何生成so文件?
Android 中生成so文件的方式有三种,第一种是通过ndk来编写so库文件(官方在下个Android Studio将删除这种方式,不建议使用)。第二种是通过ndk-build来生成so文件;第三种是通过CMake来编译生成so文件。我们着重讲解后面两种;别问我为什么,脑壳疼,谁让第一种即将被淘汰了呢!
1. 通过ndk 编译生成so(已弃用)
通过Ndk来生成so文件,我之前有写过关于此种实现的文章:NDK快速集成秘籍但是自Android Studio 3.0.1之后,使用这种方式会给如下提示,建议使用Cmake或者ndk-build集成;
Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.
Consider using CMake or ndk-build integration. For more information, go to:
https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
To get started, you can use the sample ndk-build script the Android
plugin generated for you at:
/Users/aserbao/aserbao/code/code/github/functions/audioAndvideo/ffmpeg/TestNDK/app/build/intermediates/ndk/debug/Android.mk
Alternatively, you can use the experimental plugin:
https://developer.android.com/r/tools/experimental-plugin.html
To continue using the deprecated NDK compile for another 60 days, set
android.deprecatedNdkCompileLease=1541041326840 in gradle.properties
2. 通过ndk-build编译生成so库
1. ndk-build编译单个so库
ndk-build编写so文件和ndk编写步骤上差不多,区别在于: ndk-build不需要gradle.properties文件中添加android.useDeprecatedNdk=true, 且ndk-build需要编写Android.mk文件,下面是生成的步骤:
- 创建一个调用本地方法的类文件;
新建一个项目,在MainActivity同级目录下创建CallUtils类;(路径随意,命名随意,这一步主要是为了生成对应的.h文件)我的CallUtils类代码
public class CallUtils {
static {
System.loadLibrary("use_ndk_build");
}
public static native String callSimpleInfo();
}
- 生成对应的.h代码,找到CallUtils类的路径,输入如下命令,生成对应的.h文件:
javac CallUtils.java
javac -h . CallUtils.java// java jdk 1.8以后删除javah命令了,所以我这里使用javac -h替代,如果可以使用javah可以直接使用
- 将.h文件重命名use_ndk_build.c并剪贴至jni目录下(没有请在app目录下新建jni),代码如下:
#include <jni.h>
JNIEXPORT jstring JNICALL Java_com_aserbao_aserbaosandroid_functions_how_1create_1so_useNdkBuild_CallU