当前位置: 首页 > 知识库问答 >
问题:

使用AAR和JAR源向Maven发布Android库

许正平
2023-03-14

谁能给我一个提示,告诉我如何使用maven publishGradle插件发布com.Android库带有AAR和源jar的项目/模块?我可以用旧的maven插件实现这一点,但我想使用新的maven publish插件。

共有3个答案

从阎宝
2023-03-14

通过正确的依赖项生成,对Dskinner进行一些调整:

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"
        }
    }
}

您可以通过定义以下内容来更改版本组ID

version = '1.0.0'
group = 'foo.bar'
许华清
2023-03-14

有了Android Gradle插件7.1,现在做这件事非常简单,不需要任何复杂的脚本。AGP现在还负责创建源代码和javadocs jar。

您不需要任何单独的脚本,只需将所有内容写入构建。gradle模块的文件:

plugins {
    ...
    id 'maven-publish'
}
android {
    ...
    publishing {
        singleVariant("release") {
            // if you don't want sources/javadoc, remove these lines
            withSourcesJar()
            withJavadocJar()
        }
    }
}
afterEvaluate {
    publishing {
        publications {
            release(MavenPublication) {
                from components.release
                groupId 'com.example'
                artifactId 'mylibrary'
                version = android.defaultConfig.versionName // or manually '1.0'
            }
        }
    }
}

另见:https://developer.android.google.cn/studio/build/maven-publish-plugin

更新3.3.2020:

自Android Studio 3.6发布以来,对构建AAR(甚至APK和AAB)的支持在Android Gradle插件3.6.0(以及更新版本)中实现。

我们不再需要自己处理XML依赖关系和填充内容。

以下是我对Android Studio 3.6.0的更新要点:https://gist.github.com/Robyer/a6578e60127418b380ca133a1291f017

gist代码:

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.javaCompileProvider.get().classpath
        }
    }
    exclude '**/R.html', '**/R.*.html', '**/index.html'
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    archiveClassifier.set('javadoc')
    from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
    archiveClassifier.set('sources')
    from android.sourceSets.main.java.srcDirs
}

// 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

                // Adds javadocs and sources as separate jars.
                artifact androidJavadocsJar
                artifact androidSourcesJar

                // You can customize attributes of the publication here or in module's build.gradle file (if you save this as script and include it build.gradle file, then you can just replicate this whole block there only with changed fields).
                //groupId = 'com.example'
                //artifactId = 'custom-artifact'
                version = android.defaultConfig.versionName // or just '1.0'
            }
        }
    }
}

旧答案:

这是我的改进方案,基于其他答案。

主旨:https://gist.github.com/Robyer/a6578e60127418b380ca133a1291f017

其他答案的变化:

>

  • 更改了分类器-它必须是“源”(而不是“源”
  • 处理依赖项
    • 还支持@aar可传递:false。在这种情况下,我们在POM中设置exclusion来忽略该依赖项的所有可传递依赖项。

      还支持依赖项的自定义排除规则,例如:

        compile('com.example:something:1.0', {
            exclude group: 'com.exclude.this', module: 'some-module'
        })
      

      更改日志:

      • 27.3.2018-在新的Gradle中增加了对api/实现依赖的支持
      • 23.11.2018-将bundleRelise重命名为bundleRelaseAar,因为它在新Gradle中进行了更改(请参阅此答案)
      • 23.11.2018-将getAllDependance更改为getDependence,以修复重复的结果项(如在我的要点的评论中提到的)。
      • 23.04.2019-包装在project.after评估{...}以修复新Gradle。
      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") }
                      }
                  }
              }
          }
      }
      

  • 盛浩阔
    2023-03-14

    下面是一个使用新的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"
            }
        }
    }
    

    使用发布/gradlew clean build publish

     类似资料:
    • 我用aar/apklib格式构建了自己的android libs,现在我正在寻找一种方法,在netbeans中的最终apk项目中使用它们,而不破坏maven构建。问题是:我需要包含生成的lib jar,以便让netbeans乐于为lib找到导入,但是这破坏了maven构建,因为dex发现了重复的构建配置,因为lib在pom.xml中被指定了两次(一次作为apklib/aar,一次作为jar)。

    • 我无法发布我使用maven to Nexus构建的工件的快照版本。我的工件的版本状态为1.0.0-Snapshot。 我可以毫无问题地执行。但是,当我尝试使用进行部署时,会出现以下错误:

    • 我正在使用Gradle插件0.9和Android Studio 0.5.4。 我有一个Android库项目,只有一个依赖项。jar位于/libs文件夹中。当我在Proguard激活的情况下运行AssemblerRelease任务时,生成的AAR具有以下结构: 我的图书馆 问题是myJar。jar类被合并到类中。jar by Proguard(当我在没有Proguard的情况下运行时,它不会发生)。

    • 正确地创建了Jar,并且在清单中提到了main类。我有以下几个问题: > 目标文件夹包含classes文件夹,而classes文件夹中有类文件。罐子里也有它们,所以为什么需要它们。我的目标是拥有一个只包含所有依赖项的可执行jar。 这些资源根本没有被添加到jar中。我已经根据网上看到的说明添加了变压器,但是没有用!!! 我完全没有关于如何包含资源的线索。感谢任何帮助!! 编辑:::: 这是我用于m

    • 但是,围绕这个概念,我有些怀疑。我的意思是,开发人员什么时候应该有兴趣在其应用程序中包含aar依赖项?这种依赖关系是否已收紧到某个SDK最低版本? 例如,在一个项目中,我访问一个COM端口,我使用NDK预编译的.so库。如果要共享此实用程序,是否必须创建aar?

    • 我正在使用Maven assembly插件将Java项目的二进制文件打包到一个fat jar中(带有jar-with-dependencies描述符)。这个挺管用的。 我的pom.xml如下所示: