Android发布不同的Module变体AAR到Maven库

2,198 阅读2分钟

一、背景

最近项目中有个需求,其中关键一环是发布不同Module变体到Maven库。一开始没意识到这点,通过常用的apply plugin: 'maven'插件配置写法,发现执行uploadArchives任务成功,但实际上并没有产物生成。且uploadArchives所依赖各task也并没有执行,期间无其他有效提示日志信息。后来终于想到应该是构建变体原因,经与同事交流,最终发现可以使用maven-publish插件。


二、maven-publish 插件

实际上Android官网上已经有针对不同Module变体到Maven库的指引文档,且所使用的正是maven-publish插件。

Android Gradle 插件 3.6.0 及更高版本支持 Maven Publish Gradle 插件,可让您将构建工件发布到 Apache Maven 代码库。Android Gradle 插件会为应用或库模块中的每个构建变体工件创建一个组件,您可以使用它来自定义要发布到 Maven 代码库的发布内容。

maven-publish插件功能相当强大,不仅可以区分变体发布模块AAR,同时还支持发布AAB甚至APK文件。

具体文档地址:
developer.android.com/studio/buil…
docs.gradle.org/current/use…


三、示例

1,官网发布AAR示例:

// Because the components are created only during the afterEvaluate phase, you must
// configure your publications using the afterEvaluate() lifecycle method.
afterEvaluate {
    publishing {
        publications {
            // Creates a Maven publication called "release".
            release(MavenPublication) {
                // Applies the component for the release build variant.
                from components.release

                // You can then customize attributes of the publication as shown below.
                groupId = 'com.example.MyLibrary'
                artifactId = 'final'
                version = '1.0'
            }
            // Creates a Maven publication called “debug”.
            debug(MavenPublication) {
                // Applies the component for the debug build variant.
                from components.debug

                groupId = 'com.example.MyLibrary'
                artifactId = 'final-debug'
                version = '1.0'
            }
        }
    }

2,项目中使用的配置,其中部分脚本示例:

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'

task androidJavadocs(type: Javadoc) {
    // 设置源码所在的位置
    source = android.sourceSets.main.java.srcDirs
    exclude '**/R.html', '**/R.*.html', '**/index.html'
}

// 生成javadoc.jar
task androidJavadocsJar(type: Jar) {
    // 指定文档名称
    archiveClassifier.set('javadoc')
    from androidJavadocs.destinationDir
}

// 生成sources.jar
task androidSourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    from android.sourceSets.main.java.sourceFiles
}

afterEvaluate {
    publishing {
        publications {
            thGoogleSdk(MavenPublication) {
                groupId = 'com.corn.pay'
                artifactId = project.getName()
                version = '1.1.3-SNAPSHOT'
                pom.withXml{
                    def dependenciesNode = asNode().appendNode("dependencies")
                    configurations.implementation.allDependencies.forEach(){
                        Dependency dependency ->
                            if (dependency.version != "unspecified" && dependency.name != "unspecified"){
                                def dependencyNode = dependenciesNode.appendNode('dependency')
                                dependencyNode.appendNode('groupId', dependency.group)
                                dependencyNode.appendNode('artifactId', dependency.name)
                                dependencyNode.appendNode('version', dependency.version)
                            }
                    }
                }

                artifact androidJavadocsJar
                artifact androidSourcesJar
                artifact(tasks.getByName("bundleThGoogleSdkReleaseAar"))
            }
        }

        repositories {
            maven {
                def devUrl = "https://maven.xxxx.com/nexus"
                def user = 'xxxx'
                def pass = 'yyyy'

                String target = pom_target
                if (target == "release") {
                    url = "${devUrl}/content/repositories/releases/"
                    credentials {
                        username = user
                        password = pass
                    }
                } else if (target == "local") {
                    // test, upload local maven repository
                    url = "file:" + new File(project.rootProject.rootDir, "mavenlocal").path
                } else {
                    url = "${devUrl}/content/repositories/snapshots"
                    credentials {
                        username = user
                        password = pass
                    }
                }
            }
        }
    }
}