我想做一些概念简单但找不到任何文档的事情。我有一些库,我为所有感兴趣的平台编译了SO文件。
现在我只想生成一个包含这些so文件的AAR文件。
我知道AAR文件必须具有如下结构:/jni//mylib.so
我现在所知道的是我应该生成什么样的清单/其他元数据。
理想情况下,使用Gradle生成它会很好,但我只需要完成这件事,这样写一个简单的脚本生成zip然后重命名它也是有意义的。
发布一个包含本地库的AAR是非常直接的。我发现的优点包括:
- 如果用于多个项目,当然,不复制本机代码也有好处
- 应用程序构建要快得多,因为您不必在应用程序中进行NDK编译。因此,如果本机代码更改频率较低
- 在我的案例中,与某些NDK和SDK组合不兼容。能够使用较旧的SDK构建库,并使用较新版本构建应用程序,效果非常好。(避免我的应用程序由于NDK问题而被困在旧的SDK版本上)
- 可以对库代码进行单元测试,这些代码完全独立于任何包含的应用程序。(应用程序单元测试仍然可以测试库)
权衡是有一些额外的步骤来更新c代码,但如果它的变化频率低于应用程序,那么这是一个很好的权衡。
值得注意的是,我在每个构建中都会收到一个警告:Current NDK support is deprecated. Alternative will be provided in the future.
。AFAIK,替代方案还不可用——我对弃用的定义是,在这种情况发生之前,它不会被弃用。
以下是我如何让它工作的关键点:
- c和cpp代码位于src/main/jni下
-
app/build.gradle(这也适用于在应用程序项目中使用NDK):
apply plugin: 'com.android.library'
下顶部的apply plugin: 'maven'
-
添加包含android块下目录的c/cpp头:
sourceSets.main { jni.srcDirs 'src/main/jni/Thirdparty/lib1/headers', ... }
-
在android/defaultConfig下(您的本地代码可能需要的任何选项):
ndk { moduleName "module_name" cFlags "-std=gnu++11 -D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE -D__STDC_LIMIT_MACROS -fexceptions" ldLibs "log" stl "gnustl_static" }
-
在android区块之外-告诉gradle如何将库发布到maven repo。这只是推送到本地的Android sdk repo目录,但也可以推送到共享存储库(我目前也在推送到内部的nexus repo-此处未包含的渐变代码)
uploadArchives { repositories { mavenDeployer { repository(url: "file://localhost" + System.getenv("ANDROID_HOME") + "/extras/android/m2repository/") pom.version = '1.0-SNAPSHOT' } pom.groupId = 'com.example.groupid' pom.artifactId = 'library_name' }
./gradlew uploadArchives
然后向我的本地repo发布一个有效的aar,我可以在android/dependences块下的app/build.gradle中使用compile 'com.example.groupid:library_name:1.0-SNAPSHOT'
从应用程序项目中依赖它- 在幕后,androidsdk将aar合并到应用程序的apk中,就好像它们是作为应用程序项目的一部分构建的一样(包括许多jni/*/module_name.so文件)