将本机库(SO 文件)包装到 Android 存档(aar 文件)中

Fed*_*tti 5 java-native-interface android native aar

我想做一些概念上简单但找不到任何文档的事情。我有一个特定的库,我为我感兴趣的所有平台编译了 SO 文件。

现在我只想生成一个包含这些 so 文件的 AAR 文件。

我知道 AAR 文件必须具有如下结构:/jni//mylib.so

我现在知道的是我应该生成什么样的清单/其他元数据。

理想情况下,使用 Gradle 生成它会很棒,但我只需要完成这件事,因此编写一个生成 zip 的简单脚本然后重命名它也很有意义。

Sta*_*iel 5

发布包含本机库的 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: 'maven' 在上下 apply plugin: 'com.android.library'
    • 在 android 块下添加包含目录的 c/cpp 标头:

      sourceSets.main {
        jni.srcDirs 'src/main/jni/Thirdparty/lib1/headers', ... 
      }
      
      Run Code Online (Sandbox Code Playgroud)
    • 在 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"
          }
      
      Run Code Online (Sandbox Code Playgroud)
    • 在 android 块之外 - 告诉 gradle 如何将库发布到 Maven 存储库。这只是推送到本地 Android sdk repo 目录,但也可以推送到共享存储库(我目前也在推送到内部 nexus 存储库 - 此处未包含的 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'
      }
      
      Run Code Online (Sandbox Code Playgroud)
  • ./gradlew uploadArchives然后将有效的 aar 发布到我的本地存储库,我可以从应用程序项目中依赖它,compile 'com.example.groupid:library_name:1.0-SNAPSHOT'在 android/dependencies 块下的 app/build.gradle 中使用
  • 在幕后,android sdk 将 aar 合并到应用程序的 apk 中,就好像它们是作为应用程序项目的一部分构建的(包括许多 jni/*/module_name.so 文件)

  • jni文件夹中的标题也可以打包到aar吗? (4认同)