将本机库(SO 文件)包装到 Android 存档(aar 文件)中
Wrapping native libraries (SO files) into an Android Archive (aar file)
我想做一些概念上简单但找不到任何文档的事情。我有一些库,我为我感兴趣的所有平台编译了 SO 文件。
现在我只想生成一个包含那些 so 文件的 AAR 文件。
我知道 AAR 文件必须具有如下结构:
/jni//mylib.so
我现在知道的是我应该制作什么样的 Manifest/other 元数据。
理想情况下,使用 Gradle 生成它会很棒,但我只需要完成这件事,因此编写一个生成 zip 的简单脚本然后重命名它也很有意义。
发布包含本机库的 AAR 非常好 [=70=]。我发现的优势包括:
- 如果用于多个项目,当然有不复制本机代码的好处
- 应用程序构建速度更快,因为您不必在应用程序中进行 NDK 编译。所以如果本机代码更改频率较低
- 就我而言,某些 NDK 和 SDK 组合不兼容。能够使用较旧的 SDK 构建库并使用较新版本的应用程序运行良好。 (避免我的应用因为 NDK 问题而卡在较旧的 SDK 版本上)
- 可以对完全独立于任何包含应用程序的库代码进行单元测试。 (应用程序单元测试仍然可以测试库)
权衡是有一些额外的步骤来更新 c-code,但如果它的更改频率低于应用程序,那么这是一个很好的权衡。
值得注意的是,我在每次构建时都会收到警告:Current NDK support is deprecated. Alternative will be provided in the future.
。 AFAIK,替代方案尚不可用 - 我对已弃用的定义是在发生这种情况之前它不会被弃用。
以下是我使用它的要点:
- c 和 cpp 代码位于 src/main/jni
下
app/build.gradle(其中很多也适用于在应用程序项目中使用 NDK):
apply plugin: 'maven'
在顶部 apply plugin: 'com.android.library'
添加 c/cpp header 包含 android 块下的目录:
sourceSets.main {
jni.srcDirs 'src/main/jni/Thirdparty/lib1/headers', ...
}
under 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 - gradle 此处未包含的代码)
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
然后将有效的 aar 发布到我的本地存储库,我可以从一个应用程序项目中依赖它 app/build.gradle 下的 app/build.gradle =69=]块
- 在幕后,android sdk 将 aar 合并到应用程序的 apk 中,就好像它们是作为应用程序项目的一部分构建的(包括许多 jni/*/module_name.so 文件)
我想做一些概念上简单但找不到任何文档的事情。我有一些库,我为我感兴趣的所有平台编译了 SO 文件。
现在我只想生成一个包含那些 so 文件的 AAR 文件。
我知道 AAR 文件必须具有如下结构: /jni//mylib.so
我现在知道的是我应该制作什么样的 Manifest/other 元数据。
理想情况下,使用 Gradle 生成它会很棒,但我只需要完成这件事,因此编写一个生成 zip 的简单脚本然后重命名它也很有意义。
发布包含本机库的 AAR 非常好 [=70=]。我发现的优势包括:
- 如果用于多个项目,当然有不复制本机代码的好处
- 应用程序构建速度更快,因为您不必在应用程序中进行 NDK 编译。所以如果本机代码更改频率较低
- 就我而言,某些 NDK 和 SDK 组合不兼容。能够使用较旧的 SDK 构建库并使用较新版本的应用程序运行良好。 (避免我的应用因为 NDK 问题而卡在较旧的 SDK 版本上)
- 可以对完全独立于任何包含应用程序的库代码进行单元测试。 (应用程序单元测试仍然可以测试库)
权衡是有一些额外的步骤来更新 c-code,但如果它的更改频率低于应用程序,那么这是一个很好的权衡。
值得注意的是,我在每次构建时都会收到警告:Current NDK support is deprecated. Alternative will be provided in the future.
。 AFAIK,替代方案尚不可用 - 我对已弃用的定义是在发生这种情况之前它不会被弃用。
以下是我使用它的要点:
- c 和 cpp 代码位于 src/main/jni 下
app/build.gradle(其中很多也适用于在应用程序项目中使用 NDK):
apply plugin: 'maven'
在顶部apply plugin: 'com.android.library'
添加 c/cpp header 包含 android 块下的目录:
sourceSets.main { jni.srcDirs 'src/main/jni/Thirdparty/lib1/headers', ... }
under 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 - gradle 此处未包含的代码)
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
然后将有效的 aar 发布到我的本地存储库,我可以从一个应用程序项目中依赖它 app/build.gradle 下的 app/build.gradle =69=]块- 在幕后,android sdk 将 aar 合并到应用程序的 apk 中,就好像它们是作为应用程序项目的一部分构建的(包括许多 jni/*/module_name.so 文件)