使用aar和source jar将Android库发布到Maven

lig*_*igi 49 android gradle android-library android-gradle-plugin maven-publish

有人可以给我一个关于如何使用maven-publish gradle插件发布带有aar和source jar的com.android.library项目/模块的提示吗?我可以使用旧的maven插件执行此操作 - 但我想使用新的maven-publish插件.

dsk*_*ner 64

这是使用新maven-publish插件的示例.

apply plugin: 'maven-publish'

task sourceJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier "sources"
}

publishing {
    publications {
        bar(MavenPublication) {
            groupId 'com.foo'
            artifactId 'bar'
            version '0.1'
            artifact(sourceJar)
            artifact("$buildDir/outputs/aar/bar-release.aar")
        }
    }
    repositories {
        maven {
            url "$buildDir/repo"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

发布 ./gradlew clean build publish

  • 似乎没有在生成的pom中记录依赖关系. (36认同)
  • 使用这个插件,它也会产生依赖关系到pom:https://github.com/wupdigital/android-maven-publish (3认同)
  • 在我将`classifier“ sources”替换为`classifier“ sources”`后,这对我有用。 (2认同)

Rob*_*yer 37

这是我改进的解决方案,基于其他答案.

要点: https ://gist.github.com/Robyer/a6578e60127418b380ca133a1291f017

其他答案的变化:

  • 改变了classifier- 一定是"sources"(不是 "source")
  • 处理依赖关系

    • 支持也@aartransitive: false.在这种情况下,我们在POM中设置排除以忽略此依赖项的所有传递依赖项.
    • 支持自定义排除依赖关系的规则,例如:

      compile('com.example:something:1.0', {
          exclude group: 'com.exclude.this', module: 'some-module'
      })
      
      Run Code Online (Sandbox Code Playgroud)
  • 不需要手动指定工件路径.

更新日志:

  • 27.3.2018 - 在新Gradle中添加了对api/implementation依赖关系的支持
  • 2018年11月23日 -更名bundleReleasebundleReleaseAar,因为它在新的摇篮改变(见这个答案)
  • 23.11.2018 - 更改getAllDependenciesgetDependencies修复重复的结果条目(如我的要点中的评论中所述).

apply plugin: 'maven-publish'

task androidJavadocs(type: Javadoc) {
    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
}

project.afterEvaluate {
    publishing {
        publications {
            maven(MavenPublication) {
                //groupId 'cz.example'
                //artifactId 'custom-artifact'
                //version = android.defaultConfig.versionName

                artifact bundleReleaseAar
                artifact androidJavadocsJar
                artifact androidSourcesJar

                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.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "api" dependencies (for new Gradle) as "compile" dependencies
                    configurations.api.getDependencies().each { dep -> addDependency(dep, "compile") }
                    // List all "implementation" dependencies (for new Gradle) as "runtime" dependencies
                    configurations.implementation.getDependencies().each { dep -> addDependency(dep, "runtime") }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在新的 gradle 中,它再次使用 `bundleReleaseAar` 抛出错误,但似乎我们只需要将整个 `publishing` 块包装到 `project.afterEvaluate { publishing { ... } }` 中。然后它再次工作。(我刚刚更新了答案) (2认同)

joe*_*cks 28

对dskinners进行一些调整,回答正确的依赖关系:

apply plugin: 'maven-publish'

task sourceJar(type: Jar) {
    from android.sourceSets.main.java.srcDirs
    classifier "source"
}

publishing {
    publications {
        bar(MavenPublication) {
            groupId 'com.foo'
            artifactId 'bar'
            version '0.1'
            artifact(sourceJar)
            artifact("$buildDir/outputs/aar/bar-release.aar")
            pom.withXml {
                def dependenciesNode = asNode().appendNode('dependencies')
                //Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
                configurations.compile.allDependencies.each {
                    if(it.group != null && (it.name != null || "unspecified".equals(it.name)) && it.version != null)
                    {
                        def dependencyNode = dependenciesNode.appendNode('dependency')
                        dependencyNode.appendNode('groupId', it.group)
                        dependencyNode.appendNode('artifactId', it.name)
                        dependencyNode.appendNode('version', it.version)
                    }
                }
            }
        }
    }
    repositories {
        maven {
            url "$buildDir/repo"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以改变versiongroupId定义:

version = '1.0.0'
group = 'foo.bar'
Run Code Online (Sandbox Code Playgroud)

  • 可以使用`artifact bundleRelease`而不是对aar文件名进行硬编码.条件`(it.name!= null ||"未指定".equals(it.name))`看起来不正确.你的意思是`(it.name!= null &&"unspecified"!= it.name)`? (6认同)

bva*_*rga 16

如果你想避免样板代码,因为maven-publish插件不会将依赖项写入pom.xml

试试这个插件:android-maven-publish

publishing {
    publications {
        mavenAar(MavenPublication) {
            groupId 'com.example'
            artifactId 'mylibrary'
            version '1.0.0'
            from components.android
        }
    }

    repositories {
        maven {
            url "$buildDir/releases"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止,这是解决问题的最佳方法。应该被 IMO 接受。 (2认同)
  • `android-maven-publish` 插件已被弃用,因为 `maven-publish` 已被 AGP 正式支持。使用 AGP 3.6.0 或更高版本。 (2认同)