将本机库(SO文件)封装到Android档案(aar文件)中



我想做一些概念简单但找不到任何文档的事情。我有一些库,我为所有感兴趣的平台编译了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文件)

最新更新