zoukankan      html  css  js  c++  java
  • Gradle配置:Android Library打包至Maven仓库

    开发Android Library项目,需要把aar包给商户app接入,如果按照原始的方法手动给包的话,那就太low了。而且Library中dependencies和proguard等都要商户app再写一遍,这实在是和low,对于商户来说,其实只要一句简单的代码就好了。

    compile 'xxx.xx.xx:xxx:3.x'
    1
    本文章演示如何通过在build.gradle中配置,达到自动上传library至maven仓库的效果。
    参考资料:https://github.com/JFrogDev/project-examples/tree/master/gradle-examples/4/gradle-android-aar

    先直接上代码:
    project下的build.gradle:

    buildscript {
    repositories {
    jcenter()
    maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
    classpath 'com.android.tools.build:gradle:2.1.3'
    classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.4.10"

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
    }
    }

    allprojects {
    repositories {
    jcenter()
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    library的build.gradle:

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

    android {
    publishNonDefault true
    compileSdkVersion 23
    buildToolsVersion '23.0.3'

    defaultConfig {
    minSdkVersion 14
    targetSdkVersion 23
    //在打包的aar中加入proguard文件
    consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    buildTypes {
    release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug{
    }
    }

    libraryVariants.all { variant ->
    variant.outputs.each { output ->
    def outputFile = output.outputFile
    if (outputFile != null && outputFile.name.endsWith('.aar')) {
    def fileName = getArtifactFileName()
    output.outputFile = new File(outputFile.parent, fileName)
    }
    }
    }
    }

    dependencies {
    compile 'com.android.support:support-v4:23.0.1'
    compile 'de.greenrobot:eventbus:2.4.0'
    compile files('libs/other-library.jar')
    }

    repositories {
    maven {
    url "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
    }

    publishing {
    publications {
    aar(MavenPublication) {
    groupId = GROUP
    artifactId POM_ARTIFACT_ID
    version = VERSION_NAME
    artifact "${project.buildDir}/outputs/aar/${getArtifactFileName()}"
    //generate POM file
    pom.withXml {
    def root = asNode()
    def dependenciesNode = root.appendNode('dependencies')
    def repositoriesNode = root.appendNode('repositories')
    //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) {
    def dependencyNode = dependenciesNode.appendNode('dependency')
    dependencyNode.appendNode('groupId', it.group)
    dependencyNode.appendNode('artifactId', it.name)
    dependencyNode.appendNode('version', it.version)
    }
    }
    //add the repositories exclude local repositories,such as file:/D:/AndroidSDK/extras/android/m2repository/
    project.repositories.each {
    if (!it.url.toString().startsWith('file')) {
    def repositoryNode = repositoriesNode.appendNode('repository')
    repositoryNode.appendNode('url', it.url)
    repositoryNode.appendNode('name', it.name)
    repositoryNode.appendNode('releases').appendNode("enabled",true)
    repositoryNode.appendNode('snapshots').appendNode("enabled",false)
    }
    }
    }
    }
    }
    }
    artifactory {
    contextUrl = REPOSITORY_URL
    publish {
    repository {
    // The Artifactory repository key to publish to
    repoKey = VERSION_NAME.contains("SNAPSHOT") ? SNAPSHOT_REPOSITORY_KEY : RELEASE_REPOSITORY_KEY
    username = ARTIFACTORY_USERNAME
    password = ARTIFACTORY_PASSWORD
    }
    defaults {
    // Tell the Artifactory Plugin which artifacts should be published to Artifactory.
    publications('aar')
    publishArtifacts = true
    // Properties to be attached to the published artifacts.
    properties = ['build.status': "$it.project.status".toString()]
    publishPom = true
    publishIvy = false
    }
    }
    }
    def getArtifactFileName() {
    return "${POM_ARTIFACT_ID}-${VERSION_NAME}.aar"
    }
    //在执行artifactoryPublish之前需要生成上传Maven仓库的Pom文档。
    artifactoryPublish {}.dependsOn(getTasks().getByPath(":sdk:generatePomFileForAarPublication"))
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    gradle.properties:

    #artifactory configs
    VERSION_NAME=3.7.0-SNAPSHOT
    #VERSION_NAME=3.7.0
    VERSION_CODE=31
    GROUP=com.example.yourproject
    POM_ARTIFACT_ID=libraryname
    POM_NAME=libraryname
    POM_PACKAGING=aar
    #你要上传的maven仓库地址
    REPOSITORY_URL=http://mvn.hz.com/artifactory
    #仓库的具体两个小位置,一个是snapshot和releases,这两个的区别自行上网查找。snapshot是快照,可以存放用于测试的包,release就是正式发布的包
    SNAPSHOT_REPOSITORY_KEY=libs-snapshots
    RELEASE_REPOSITORY_KEY=libs-releases
    #在gradle.properties中增加string变量不需要'或者",直接填写内容即可。这两个变量是上传maven仓库的账户和密码,在我的例子中上传不需要账户密码,就置为空了
    ARTIFACTORY_USERNAME=
    ARTIFACTORY_PASSWORD=
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    代码已上完,分批来看下:

    apply plugin: 'com.jfrog.artifactory'
    apply plugin: 'maven-publish'
    1
    2
    这里是我们要使用的插件,主要使用这两个插件来上传至maven仓库。

    consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    1
    这句是在打的包中加入混淆规则,这样商户app在接入的时候,不用再去关心你的library的混淆规则。如果你不加这句,那么你要告诉你商户app要keep住哪些。。。

    libraryVariants.all { variant ->
    variant.outputs.each { output ->
    def outputFile = output.outputFile
    if (outputFile != null && outputFile.name.endsWith('.aar')) {
    def fileName = getArtifactFileName()
    output.outputFile = new File(outputFile.parent, fileName)
    }
    }
    }

    def getArtifactFileName() {
    return "${POM_ARTIFACT_ID}-${VERSION_NAME}.aar"
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    这句只是修改每次编译生成的aar包的名字。上述两部分组成。

    下面分两部分,第一步是生成pom文档和aar包。第二部是将pom和aar包上传至maven仓库。
    先看下第一步

    publishing {
    publications {
    aar(MavenPublication) {
    groupId = GROUP
    artifactId POM_ARTIFACT_ID
    version = VERSION_NAME
    artifact "${project.buildDir}/outputs/aar/${getArtifactFileName()}"
    //generate POM file
    pom.withXml {
    def root = asNode()
    def dependenciesNode = root.appendNode('dependencies')
    def repositoriesNode = root.appendNode('repositories')
    //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) {
    def dependencyNode = dependenciesNode.appendNode('dependency')
    dependencyNode.appendNode('groupId', it.group)
    dependencyNode.appendNode('artifactId', it.name)
    dependencyNode.appendNode('version', it.version)
    }
    }
    //add the repositories exclude local repositories,such as file:/D:/AndroidSDK/extras/android/m2repository/
    project.repositories.each {
    if (!it.url.toString().startsWith('file')) {
    def repositoryNode = repositoriesNode.appendNode('repository')
    repositoryNode.appendNode('url', it.url)
    repositoryNode.appendNode('name', it.name)
    repositoryNode.appendNode('releases').appendNode("enabled",true)
    repositoryNode.appendNode('snapshots').appendNode("enabled",false)
    }
    }
    }
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    这里会生成pom文档,pom主要就是对你的library的一个描述,看个例子:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.yourproject</groupId>
    <artifactId>libraryname</artifactId>
    <version>3.7.0-SNAPSHOT</version>
    <packaging>aar</packaging>
    <dependencies>
    <dependency>
    <groupId>com.android.support</groupId>
    <artifactId>support-v4</artifactId>
    <version>23.0.1</version>
    </dependency>
    <dependency>
    <groupId>de.greenrobot</groupId>
    <artifactId>eventbus</artifactId>
    <version>2.4.0</version>
    </dependency>
    </dependencies>
    <repositories>
    <repository>
    <url>https://jcenter.bintray.com/</url>
    <name>BintrayJCenter</name>
    <releases>
    <enabled>true</enabled>
    </releases>
    <snapshots>
    <enabled>false</enabled>
    </snapshots>
    </repository>
    </repositories>
    </project>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    所以在我们的例子中加入了library依赖的dependency和repository。如果不加dependency的话,在商户app中需要再加入library的依赖项。
    !!!!但是!!!!加入repository好像没用,我依旧要在商户app中加入repository,目前还没找到为什么,读者若知道和我说下!!!!
    生成aar的话,就调用gradle的assembleRelease就好了。

    第二步上传至maven:

    artifactory {
    contextUrl = REPOSITORY_URL
    publish {
    repository {
    // The Artifactory repository key to publish to
    repoKey = VERSION_NAME.contains("SNAPSHOT") ? SNAPSHOT_REPOSITORY_KEY : RELEASE_REPOSITORY_KEY
    username = ARTIFACTORY_USERNAME
    password = ARTIFACTORY_PASSWORD
    }
    defaults {
    // Tell the Artifactory Plugin which artifacts should be published to Artifactory.
    publications('aar')
    publishArtifacts = true
    // Properties to be attached to the published artifacts.
    properties = ['build.status': "$it.project.status".toString()]
    publishPom = true
    publishIvy = false
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    其实也很简单,就是指明仓库地址,账户密码,类型等就好了。

    这时候sync下你的代码,会发现在gradle task中多了几个task。

    artifactoryPublish就是上传aar到maven中,也就是我们刚刚说的第二步。
    generatePomFileForAarPublication就是生成pom文档,也就是我们刚刚说的第一步。
    后面三个我就不太清楚具体是干嘛的。

    如果你直接执行artifactoryPublish的话,可能会出错,因为你可能还没生成pom文档。所以我在build.gradle中加了一句依赖:

    //在执行artifactoryPublish之前需要生成上传Maven仓库的Pom文档。
    artifactoryPublish {}.dependsOn(getTasks().getByPath(":sdk:generatePomFileForAarPublication"))
    1
    2
    这句话的意思就是在执行artifactoryPublish任务之前,需要执行generatePomFileForAarPublication。这样就不会出错了。

    好了,现在双击artifactoryPublish任务进行上传,看下结果:


    下面给出了引用的代码:

    compile(group: 'com.example.yourproject', name: 'libraryname', version: '3.7.0-20161213.023523-29', ext: 'aar')
    1
    2
    好了,在商户app中只用加入这一句就好了。
    加入之后,build之后你会发现刚刚library项目中的eventbus和support库都会自动导进来了,而商户app中却不用声明,是否很简单易用呢?

    接下来讲下遇到的坑吧:
    1.pom文件中配置的repository不管用,就是说pom中的依赖项并不从我配置的repositories中寻找,所以别人加入你的aar的话,还需要在build.gradle中加入你使用的仓库。
    2.在repository节点中,有个属性叫做updatePolicy,updatePolicy更新snapshot包的频率,属性有四个值always(实时更新) daily(每天更新) interval:xxx(隔xxx分钟更新一次) never(从不更新) 默认为daily ,如果repository节点不起作用的话,那么policy不起作用的话,如何你不更新版本号就在原来的版本上发布的话,可能会拉取不到最新的包。
    目前看到一种解决办法是只需执行一下mvn clean install 即可完成依赖更新,完成以上操作可完成无需更改版本发布,依赖方也不需要更改pom。


    ————————————————
    版权声明:本文为CSDN博主「写Android的媛运气不会太差」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/lintcgirl/article/details/53607674

  • 相关阅读:
    Boost Log : Trivial logging
    Boost Log : Definitions
    Boost Log : Setting up sinks
    Boost Log
    VS工程文件记录
    vs2017激活密钥
    JWT库
    Mac 使用 NFS 连接 Centos 上的共享文件夹
    Mahout源码目录说明
    linux中的线程同步:生产者、消费者问题
  • 原文地址:https://www.cnblogs.com/javalinux/p/15401316.html
Copyright © 2011-2022 走看看