美文网首页gradle
安卓(Android) 发布 aar 到 maven 服务器或是

安卓(Android) 发布 aar 到 maven 服务器或是

作者: 鱿鱼鉄板燒 | 来源:发表于2018-07-19 16:42 被阅读0次

    1. 创建修改已有代码成为安卓库项目

    大家手上都或多或少有些项目可以封装成 aar 共享给其他同学。或是公司相关的库需要封装并发布给项目使用。你可以创建一个安卓 library工程,可以参考官方文档 Create an Android library
    这个步骤就不在具体细讲,不是本文的主题。
    更新记录:

    1. 2018-12-06:修改maven服务器账号,密码,版本号的获取方式。解决账号保护的问题,针对使用CI/CD进行发布。

    2. 修改库工程的 build.gradle 文件

    找到你的 library 工程的 build.gradle 文件。
    下图是我的私人工程的文件目录结构,其中 audiocore 是 android library project。


    打开 audiocore/build.gradle 在尾部追加如下代码:
    apply plugin: 'maven-publish'
    
    def getRepositoryUsername() {
      Properties properties = new Properties()
      properties.load(project.rootProject.file('local.properties').newInputStream())
    
      def MAVEN_USERNAME_LOCAL = properties.getProperty('MAVEN_USERNAME')
      return hasProperty('MAVEN_USERNAME') ? MAVEN_USERNAME : MAVEN_USERNAME_LOCAL;
    }
    
    def getRepositoryPassword() {
      Properties properties = new Properties()
      properties.load(project.rootProject.file('local.properties').newInputStream())
    
      def MAVEN_PASSWORD_LOCAL = properties.getProperty('MAVEN_PASSWORD')
      return hasProperty('MAVEN_PASSWORD') ? MAVEN_PASSWORD : MAVEN_PASSWORD_LOCAL
    }
    
    def getVersionName() {
      def local_version_name = "version-default-SNAPSHOT"
      if (hasProperty("VERSION_NAME")) {
          local_version_name = getProperty("VERSION_NAME")
      }
      return local_version_name
    }
    
    task androidJavadocs(type: Javadoc) {
      failOnError false
      source = android.sourceSets.main.java.srcDirs
      classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
      android.libraryVariants.all { variant ->
        if (variant.name == 'release') {
            owner.classpath += variant.javaCompile.classpath
        }
      }
      exclude '**/R.html', '**/R.*.html', '**/index.html'
    }
    
    task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
      classifier = 'javadoc'
      from androidJavadocs.destinationDir
    }
    
    task androidSourcesJar(type: Jar) {
      classifier = 'sources'
      from android.sourceSets.main.java.srcDirs
    }
    
    publishing {
      publications {
      Production(MavenPublication) {
        artifactId = POM_ARTIFACT_ID
        groupId = POM_GROUP_ID
        version = getVersionName()
    
        artifact bundleRelease
        artifact androidJavadocsJar
        artifact androidSourcesJar
    
        // The publication doesn't know about our dependencies, so we have to manually add them to the pom
        pom.withXml {
    
            final dependenciesNode = asNode().appendNode('dependencies')
    
            ext.addDependency = { Dependency dep, String scope ->
                if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified")
                    return // ignore invalid dependencies
    
                final dependencyNode = dependenciesNode.appendNode('dependency')
                dependencyNode.appendNode('groupId', dep.group)
                dependencyNode.appendNode('artifactId', dep.name)
                dependencyNode.appendNode('version', dep.version)
                dependencyNode.appendNode('scope', scope)
    
                if (!dep.transitive) {
                    // If this dependency is transitive, we should force exclude all its dependencies them from the POM
                    final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                    exclusionNode.appendNode('groupId', '*')
                    exclusionNode.appendNode('artifactId', '*')
                } else if (!dep.properties.excludeRules.empty) {
                    // Otherwise add specified exclude rules
                    final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
                    dep.properties.excludeRules.each { ExcludeRule rule ->
                        exclusionNode.appendNode('groupId', rule.group ?: '*')
                        exclusionNode.appendNode('artifactId', rule.module ?: '*')
                    }
                }
            }
    
            // List all "compile" dependencies (for old Gradle)
            configurations.compile.getAllDependencies().each { dep -> addDependency(dep, "compile") }
            // List all "api" dependencies (for new Gradle) as "compile" dependencies
            configurations.api.getAllDependencies().each { dep -> addDependency(dep, "compile") }
            // List all "implementation" dependencies (for new Gradle) as "runtime" dependencies
            configurations.implementation.getAllDependencies().each { dep -> addDependency(dep, "runtime") }
        }
      }
    
    }
    
    repositories {
      maven {
        // change URLs to point to your repos, e.g. http://my.org/repo
        //  def releasesRepoUrl = "$buildDir/repos/releases"
        //  def snapshotsRepoUrl = "$buildDir/repos/snapshots"
        // 测试阶段可以使用以上两个本地地址变量
        def releasesRepoUrl = "http://my.org/repo/movie-release" // change to your self repo url
        def snapshotsRepoUrl = "http://my.org/repo/movie-snapshot"  // change to your self snapshot repo url
        url = getVersionName().endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
        credentials {
            username getRepositoryUsername() 
            password getRepositoryPassword()
          }
        }
      }
    }
    

    使用上面代码会需要3个变量,我们将他们添加到 gradle.properties 文件里面:

    POM_ARTIFACT_ID=audiocore
    POM_GROUP_ID=com.javan.movie
    VERSION_NAME=0.1.0.2-SNAPSHOT  // 如果发布非 SNAPSHOT快照版本的时候删除尾部版本的 -SNAPSHOT
    

    3. 执行发布命令

    打开 Gradle 控制窗口如下图:


    双击执行 publish 的 task。
    如果成功会出现如下日志:

    4. 测试发布是否成功

    在 app 工程的 build.gradle 修改依赖的写法:

    dependencies {
      implementation fileTree(dir: 'libs', include: ['*.jar'])
      // implementation project(':audiocore')
      implementation "com.javan.movie:audiocore:0.1.0.2-SNAPSHOT" //修改此处的 group id、库名称、 version name
      implementation 'com.android.support:appcompat-v7:27.0.2'
    }
    

    通过下工程如何通过,说明整体已经跑通。

    5. 优化配置

    从上面的配置上有个缺陷,它会暴露你的 Maven 服务器的账号和密码。而且这个账号密码也不适合提交到代码仓库里面。目前有两种解决方案:

    1. 将私有的Maven服务器上传权限关闭账号验证

    简单说就是任何人都可以往你的私人服务器发布AAR或JAR,取消账号验证。修改配置文件

    repositories {
        maven {
            // change URLs to point to your repos, e.g. http://my.org/repo
            //  def releasesRepoUrl = "$buildDir/repos/releases"
            //  def snapshotsRepoUrl = "$buildDir/repos/snapshots"
            // 测试阶段可以使用以上两个本地地址变量
            def releasesRepoUrl = "http://my.org/repo/movie-release" // change to your self repo url
            def snapshotsRepoUrl = "http://my.org/repo/movie-snapshot"  // change to your self snapshot repo url
            url = VERSION_NAME.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
            /*
            credentials {
                username '<your account name>'
                password '<your account password>'
            }*/
        }
      }
    }
    

    2. 在环境变量里面配置 Maven 账号和密码

      ➜  ~ echo "export ORG_GRADLE_PROJECT_MAVEN_PASSWORD=<your account password>" >> ~/.bash_profile
      ➜  ~ echo "export ORG_GRADLE_PROJECT_MAVEN_USERNAME=<your account name>" >> ~/.bash_profile
      ➜  source ~/.bash_profile
    

    这个命名规则可以使得在 Gradle 编译环境变量里面出现 MAVEN_USERNAME, MAVEN_PASSWORD 这两个参数可以直接在 build.gradle 文件访问。

    然后修改:

      repositories {
        maven {
            // change URLs to point to your repos, e.g. http://my.org/repo
            //  def releasesRepoUrl = "$buildDir/repos/releases"
            //  def snapshotsRepoUrl = "$buildDir/repos/snapshots"
            // 测试阶段可以使用以上两个本地地址变量
            def releasesRepoUrl = "http://my.org/repo/movie-release" // change to your self repo url
            def snapshotsRepoUrl = "http://my.org/repo/movie-snapshot"  // change to your self snapshot repo url
            url = VERSION_NAME.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
            credentials {
                username MAVEN_USERNAME
                password MAVEN_PASSWORD
            }
        }
      }
    }
    

    再重复执行一次第三的步骤。如果找不到变量,可以重新下 Android Stuido 让前面的配置生效。

    总结

    使用maven进行安卓库的发布,不仅减少了与项目或是其他同学私下给库带来的风险,也给库添加了版本管理。方便代码追溯。并且我们也配置了发布 sources.jar 这样配合的同学也可以调试项目的 java 层工程。方便相关同学进行错误的辅助定位。提升开发效率。当然对于一些存在保密性的代码,就不建议把 sources.jar 发布出来。

    artifact bundleRelease
    artifact androidJavadocsJar
    // artifact androidSourcesJar // 关闭源代码文件发布。
    

    相关文章

      网友评论

        本文标题:安卓(Android) 发布 aar 到 maven 服务器或是

        本文链接:https://www.haomeiwen.com/subject/awetmftx.html