Gradle配置:Android Library打包至Maven仓库
2016-12-13 11:21
573 查看
开发Android Library项目,需要把aar包给商户app接入,如果按照原始的方法手动给包的话,那就太low了。而且Library中dependencies和proguard等都要商户app再写一遍,这实在是和low,对于商户来说,其实只要一句简单的代码就好了。
本文章演示如何通过在build.gradle中配置,达到自动上传library至maven仓库的效果。
参考资料:https://github.com/JFrogDev/project-examples/tree/master/gradle-examples/4/gradle-android-aar
先直接上代码:
project下的build.gradle:
library的build.gradle:
gradle.properties:
代码已上完,分批来看下:
这里是我们要使用的插件,主要使用这两个插件来上传至maven仓库。
这句是在打的包中加入混淆规则,这样商户app在接入的时候,不用再去关心你的library的混淆规则。如果你不加这句,那么你要告诉你商户app要keep住哪些。。。
这句只是修改每次编译生成的aar包的名字。上述两部分组成。
下面分两部分,第一步是生成pom文档和aar包。第二部是将pom和aar包上传至maven仓库。
先看下第一步
这里会生成pom文档,pom主要就是对你的library的一个描述,看个例子:
所以在我们的例子中加入了library依赖的dependency和repository。如果不加dependency的话,在商户app中需要再加入library的依赖项。
!!!!但是!!!!加入repository好像没用,我依旧要在商户app中加入repository,目前还没找到为什么,读者若知道和我说下!!!!
生成aar的话,就调用gradle的assembleRelease就好了。
第二步上传至maven:
其实也很简单,就是指明仓库地址,账户密码,类型等就好了。
这时候sync下你的代码,会发现在gradle task中多了几个task。
artifactoryPublish就是上传aar到maven中,也就是我们刚刚说的第二步。
generatePomFileForAarPublication就是生成pom文档,也就是我们刚刚说的第一步。
后面三个我就不太清楚具体是干嘛的。
如果你直接执行artifactoryPublish的话,可能会出错,因为你可能还没生成pom文档。所以我在build.gradle中加了一句依赖:
这句话的意思就是在执行artifactoryPublish任务之前,需要执行generatePomFileForAarPublication。这样就不会出错了。
好了,现在双击artifactoryPublish任务进行上传,看下结果:
下面给出了引用的代码:
好了,在商户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。
compile 'xxx.xx.xx:xxx:3.x'
本文章演示如何通过在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() } }
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"))
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=
代码已上完,分批来看下:
apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish'
这里是我们要使用的插件,主要使用这两个插件来上传至maven仓库。
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
这句是在打的包中加入混淆规则,这样商户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" }
这句只是修改每次编译生成的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) } } } } } }
这里会生成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>
所以在我们的例子中加入了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 } } }
其实也很简单,就是指明仓库地址,账户密码,类型等就好了。
这时候sync下你的代码,会发现在gradle task中多了几个task。
artifactoryPublish就是上传aar到maven中,也就是我们刚刚说的第二步。
generatePomFileForAarPublication就是生成pom文档,也就是我们刚刚说的第一步。
后面三个我就不太清楚具体是干嘛的。
如果你直接执行artifactoryPublish的话,可能会出错,因为你可能还没生成pom文档。所以我在build.gradle中加了一句依赖:
//在执行artifactoryPublish之前需要生成上传Maven仓库的Pom文档。 artifactoryPublish {}.dependsOn(getTasks().getByPath(":sdk:generatePomFileForAarPublication"))
这句话的意思就是在执行artifactoryPublish任务之前,需要执行generatePomFileForAarPublication。这样就不会出错了。
好了,现在双击artifactoryPublish任务进行上传,看下结果:
下面给出了引用的代码:
compile(group: 'com.example.yourproject', name: 'libraryname', version: '3.7.0-20161213.023523-29', ext: 'aar')
好了,在商户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。
相关文章推荐
- Android使用gradle不同配置多项目打包(升级版)
- Android 一站式打包(一)gradle 动态配置多环境
- Android使用gradle不同配置多项目打包
- Android 使用gradle打包的各种配置
- MAC下配置gradle用eclipse 打包android程序
- Android 使用gradle打包的各种配置
- Android 使用gradle配置多环境打包
- Android Studio Gradle多渠道打包(动态设定App名称,应用图标,背景图片,状态栏颜色)、配置签名文件
- Android打包&Gradle配置(一)
- Android Gradle 配置打包输出名称格式
- Gradle for Android(三)多渠道打包、配置签名信息
- [Android]配置Gradle的productFlavors构建项目用于多渠道打包或多环境运行
- Android使用Gradle进行打包混淆,包括依赖Library
- android 多渠道打包,build.gradle文件配置、manifest文件配置
- Mac电脑配置Gradle,实现android自动打包
- Gradle for Android(三)多渠道打包、配置签名信息
- jenkins+gradle配置android app打包(环境准备)
- android项目从零开始 gradle 打包差别配置 区分
- Android使用gradle不同配置多项目打包
- Android Gradle全局配置、关闭Log、多渠道打包