Android AAR包为本地库

我正在寻找一种方法将本地库打包到AAR包中,所以可以通过gradle脚本中的依赖声明来使用它。

通过本地库,我的意思是一组.cpp文件或编译静态库和一组头文件。 所以,我的意思是应用程序本身将从本地代码调用库,而不是从Java调用。 换句话说,库需要编译应用程序的本机代码。 这样就可以轻松pipe理本机代码的依赖关系。

这甚至有可能吗?

到目前为止,我只能find很多关于如何使用.so文件和它的Java接口来创buildJNI本地库的AAR的问题/例子,所以lib只是一个具有本地实现的Java库,但这不是我所需要的。

Solutions Collecting From Web of "Android AAR包为本地库"

发现了以下这个问题的解决办法:

使用Android实验Gradle插件0.9.1版本。 这个想法是把库标题和静态库放到.aar中。 对于每个体系结构,头文件都放在ndkLibs/include和静态库文件中,放在ndkLibs/<arch>中。 然后,在应用程序或依赖于这个打包的lib的另一个lib中,我们只需从AAR ndkLibs目录从项目中的build目录中提取ndkLibs 。 请参阅下面的示例gradle文件。

具有注释的库的build.gradle文件:

 apply plugin: "com.android.model.library" model { android { compileSdkVersion = 25 buildToolsVersion = '25.0.2' defaultConfig { minSdkVersion.apiLevel = 9 targetSdkVersion.apiLevel = 9 versionCode = 1 versionName = '1.0' } ndk { platformVersion = 21 moduleName = "mylib" toolchain = 'clang' abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default ldLibs.addAll(['android', 'log']) stl = 'c++_static' cppFlags.add("-std=c++11") cppFlags.add("-fexceptions") cppFlags.add("-frtti") //Add include path to be able to find headers from other AAR libraries cppFlags.add("-I" + projectDir.getAbsolutePath() + "/build/ndkLibs/include") } //For each ABI add link-time library search path to be able to link against other AAR libraries abis { create("armeabi") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/armeabi") } create("armeabi-v7a") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/armeabi-v7a") } create("arm64-v8a") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/arm64-v8a") } create("x86") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/x86") } create("x86_64") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/x86_64") } create("mips") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/mips") } create("mips64") { ldFlags.add("-L" + projectDir.getAbsolutePath() + "/build/ndkLibs/mips64") } } } //Configure this library source files android.sources { main { jni { //This does not affect AAR packaging exportedHeaders { srcDir "../../src/" } //This tells which source files to compile source { srcDirs '../../src' } } } } } //Custom Maven repository URLs to download AAR files from repositories { maven { url 'https://dl.bintray.com/igagis/android/' } } //Our custom AAR dependencies, those in turn are also packed to AAR using the same approach dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'io.github.igagis:libutki:+' compile 'io.github.igagis:libsvgdom:+' compile 'org.cairographics:cairo:+' } //=================================== //=== Extract NDK files from AARs === //This is to automatically extract ndkLibs directory from AAR to build directory before compiling any sources task extractNDKLibs { doLast { configurations.compile.each { def file = it.absoluteFile copy { from zipTree(file) into "build/" include "ndkLibs/**/*" } } } } build.dependsOn('extractNDKLibs') tasks.whenTaskAdded { task -> if (task.name.startsWith('compile')) { task.dependsOn('extractNDKLibs') } } //================================= //=== pack library files to aar === //This stuff re-packs the release AAR file adding headers and static libs to there, but removing all shared (.so) libs, as we don't need them. The resulting AAR is put to the project root directory and can be uploaded to Maven along with POM file (you need to write one by hand). def aarName = name task copyNdkLibsToAAR(type: Zip) { baseName = aarName version = "\$(version)" extension = 'aar.in' destinationDir = file('..') //put resulting AAR file to upper level directory from zipTree("build/outputs/aar/" + aarName + "-release.aar") exclude('**/*.so') //do not include shared libraries into final AAR from("../../src") { exclude('makefile') exclude('soname.txt') exclude('**/*.cpp') exclude('**/*.c') into('ndkLibs/include') } from("build/intermediates/binaries/debug/lib"){ include('**/*.a') into('ndkLibs') } } build.finalizedBy('copyNdkLibsToAAR') 

从这个链接 ,它看起来不可能。 我正在粘贴下面的内容:

AAR文件的解剖

AAR文件的文件扩展名是.aar,Maven工件types也应该是空的。 该文件本身是一个包含以下必需条目的zip文件:

  • /AndroidManifest.xml
  • /classes.jar
  • / RES /
  • /R.txt

此外,AAR文件可能包含一个或多个以下可选条目:

  • /资产/
  • /libs/name.jar
  • /jni/abi_name/name.so(其中abi_name是Android支持的ABI之一)
  • /proguard.txt
  • /lint.jar

如上所述,强制性条目包括一个jar子。 然而,你可以试试手动删除jar文件,通过解压aar和zip回来。 我不确定它是否会工作。

虽然我没有亲自尝试过,但我在这里find了一些步骤:

大概是间接的(前一阵子试用共享库),我个人认为这是不值得的:

  • 先build立你的lib来生成一个静态库,然后一个[model.library不会把* .a放到libs目录中]
  • 解压缩你的aar,把* .a放到libs文件夹中
  • find你的头文件的地方
  • 将它拉回到你的应用程序的内部,使得它成为你的依赖库,所以它将被提取到爆炸文件夹中; 那么彩色图片出现。
  • 添加中间爆炸aar目录到包含path我认为这太hacky,可能不是一个好主意强加给你的客户。

传统的直接分发lib和头文件的方式还是比上面的黑客更好一些。 对于构build库,cmake方式好多了,checkout hello-libs在master-cmake分支,希望这有助于