【我的Android进阶之旅】快速创建和根据不同的版本类型(Dev、Beta、Release)发布Android 开发库到Maven私服

简介: 前言由于项目越来越多,有很多公共的代码都可以抽取出一个开发库出来传到公司搭建好的Maven私服,以供大家使用。之前搭建的Maven仓库只有Release和Snapshot两个仓库,最近由于开发库有时候不稳定有bug,不便于测试。

前言

由于项目越来越多,有很多公共的代码都可以抽取出一个开发库出来传到公司搭建好的Maven私服,以供大家使用。

之前搭建的Maven仓库只有Release和Snapshot两个仓库,最近由于开发库有时候不稳定有bug,不便于测试。因此领导说要搭建三个版本的仓库,分别为Release版本、Beta版本、Dev版本,Snapshot版本废弃掉,下面来分别介绍下这三个版本仓库的意义。

  1. Dev版本:是用于开发库维护人员能够很快的新增代码并上传到Maven仓库,这样其他开发人员就能够很快的获取该Dev版本的Android 开发库进行开发。
  2. Beta版本:用于当使用Dev版本提供的开发库开发功能,并且功能开发完毕之后,准备提测给测试人员测试功能的时候,将最新的稳定的Dev版本代码上传到Beta仓库变成Beta版本,Beta版本的开发库较Dev版本稳定。
  3. Release版本:用于测试人员测试完使用Beta版本提供的开发库开发完毕功能点,并且功能点稳定,准备发布APP的时候,最新的稳定的Beta版本代码上传到Release仓库变成Release版本,Release版本的开发库较Beta版本稳定。

下面是我最近搭建的这三个版本Release版本、Beta版本、Dev版本的仓库的截图。

这里写图片描述

至于这三个版本Release版本、Beta版本、Dev版本的仓库如何新建,我准备在下一篇博客再写,因为一般搭建仓库的活不用每个人干,但是上传Android开发库到Maven私服的需求应该很多人都有。所以这篇博客先介绍如何快速创建和发布Android 开发库到Maven私服。


一、准备好要上传的Android 开发库

新建一个工程,如下图所示:
这里写图片描述

如上图所示,新建一个工程MavenTest,然后新建一个Module(模块)名为ouyangpeng,这个名为ouyangpeng的Module就是我们准备测试打包成AAR上传到Maven私服的开发库。

新建好 ouyangpeng 模块之后,在settings.gradle文件中,将该module加入进去,用于编译,这一步Android Studio会自动添加好。
settings.gradle文件文件代码如下:

include ':app', ':ouyangpeng'

在该Module里面随便新建一个类,名为MavenTest.java,代码如下所示:

package test.maven.xtc.com.ouyangpeng;

/**
 * 测试上传Android开发库AAR文件到Maven私服
 * </p>
 * created by OuyangPeng at 2017/2/24 19:06
 *
 * 博客地址:http://blog.csdn.net/ouyang_peng/
 */
public class MavenTest {
    /**
     * 测试Maven注释
     */
    private String mMaven = "maven";

    public String getMaven() {
        return mMaven;
    }

    public void setMaven(String maven) {
        mMaven = maven;
    }
}

ouyangpeng 模块的build.gradle文件为

apply plugin: 'com.android.library'
apply from: 'maven_upload.gradle'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.0'
    testCompile 'junit:junit:4.12'
}

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:
http://blog.csdn.net/ouyang_peng/article/details/56872556

这里写图片描述


二、编写上传Maven私服的脚本

第二步,编写上传ouyangpeng 模块打包成AAR之后上传到Maven私服的gradle脚本
首先先大致的讲解下,我会新建的三个文件的作用,如下图所示:
这里写图片描述

  1. maven_upload.gradle,该gradle脚本主要是上传Maven的gradle脚本,该脚本会去读取maven_pom.properties配置文件和maven_user.properties配置文件的内容。
  2. maven_pom.properties,该配置文件主要是配置了要打包生成后的AAR包上传到Maven私服之后的一些Maven属性,主要包括groupId属性,artifactId属性,version属性,type属性等。
  3. maven_user.properties,该配置文件主要是配置了Maven私服上的Release版本、Beta版本、Dev版本的仓库,以及用户名和密码等基本配置。

下面我们来具体的的讲解这几个文件。

2.1 maven_upload.gradle文件

在 ouyangpeng 模块中的build.gradle文件中,我们发现了有这么一段代码

apply plugin: 'com.android.library'
apply from: 'maven_upload.gradle'

这段代码的意思是,第一行代码将模块ouyangpeng生成为library类型的开发库,第二行代码的意思是引用名为maven_upload.gradle的gradle文件到该build.gradle文件中。

maven_upload.gradle文件代码如下:

apply plugin: 'maven'
//读取第一个配置文件 maven_user.properties
Properties user_properties = new Properties()
user_properties.load(project.rootProject.file('maven_user.properties').newDataInputStream())

def releaseRepoUrl = user_properties.getProperty("repository.url.release")
def betaRepoUrl = user_properties.getProperty("repository.url.beta")
def devRepoUrl = user_properties.getProperty("repository.url.dev")

def userName = user_properties.getProperty("repository.user")
def userPassword = user_properties.getProperty("repository.password")

//读取第二个配置文件 maven_pom.properties
Properties pom_properties = new Properties()
pom_properties.load(project.file('maven_pom.properties').newDataInputStream())

def pom_name = pom_properties.getProperty("POM_NAME")
def pom_description = pom_properties.getProperty("POM_DESCRIPTION")
def pom_group = pom_properties.getProperty("POM_GROUP")
def pom_artifact_id = pom_properties.getProperty("POM_ARTIFACT_ID")
def pom_packaging = pom_properties.getProperty("POM_PACKAGING")

def pom_version_type = pom_properties.getProperty("POM_VERSION_TYPE")
def pom_version_release = pom_properties.getProperty("POM_VERSION_RELEASE")
def pom_version_dev = pom_properties.getProperty("POM_VERSION_DEV")
def pom_version_beta = pom_properties.getProperty("POM_VERSION_BETA")

def repoUrl
def pom_version

uploadArchives {
    if (pom_version_type.equals("DEV")) {
        repoUrl = devRepoUrl
        pom_version = pom_version_dev
    } else if (pom_version_type.equals("BETA")){
        repoUrl = betaRepoUrl
        pom_version = pom_version_beta
    } else if (pom_version_type.equals("RELEASE")){
        repoUrl = releaseRepoUrl
        pom_version = pom_version_release
    } else {
        throw Exception(">>>>>>>>>>>>>>上传失败,POM_VERSION_TYPE = "+pom_version_type+" ,请确认maven_user.properties文件中 POM_VERSION_TYPE 参数填写正确,POM版本必须为(DEV、BETA、RELEASE)中的一种类型<<<<<<<<<<");
    }
    println "pom_version_type = " + pom_version_type
    println "pom_version = " + pom_version
    println "repoUrl = " + repoUrl +"\n"

    repositories.mavenDeployer {
        repository(url: repoUrl) {
            authentication(userName: userName,
                    password: userPassword)
        }

        pom.project {
            name pom_name
            description pom_description
            url repoUrl
            groupId pom_group
            artifactId pom_artifact_id
            version pom_version
            packaging pom_packaging
        }
    }
}

task cleanDir(type:Delete) {
    delete buildDir
}

task androidJavadocs(type: Javadoc) {
    // 设置源码所在的位置
    source = android.sourceSets.main.java.sourceFiles
}

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

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

//是否是开发版本
def isDevOrBetaBuild(String version) {
    if (version == null || version.isEmpty()){
        throw Exception(">>>>>>>>>>>>>>编译失败,POM_VERSION_TYPE = "+pom_version_type+" ,请确认maven_user.properties文件中 POM_VERSION_TYPE 参数填写正确,POM版本必须为(DEV、BETA、RELEASE)中的一种类型<<<<<<<<<<");
    }
    return version.contains("Dev") || version.contains("Beta");
}

artifacts {
    if (isDevOrBetaBuild(pom_version)) {
        archives androidSourcesJar
        archives androidJavadocsJar
    }
}
uploadArchives.mustRunAfter 'cleanDir'

该gradle脚本主要是上传Maven的gradle脚本,该脚本会去读取maven_pom.properties配置文件和maven_user.properties配置文件的内容,然后新建一个upload任务Task,一旦你准备发布你的开发库,在 Android Studio 中, 打开右侧的 Gradle 视图,在 Tasks > upload 下,点击 uploadArchives,将会上传你的开发库到你所定义好的Maven私服的仓库上去。如下图所示:
这里写图片描述

该脚本在上传到Maven仓库之前,会判断要上传的是什么版本的AAR,如果是Dev和Beta版本的AAR的话,上传之后的AAR文件在用的时候可以看到AAR里面的类的注释,如果是Release版本的AAR的话,将看不到AAR里面的类的注释

2.2 maven_user.properties配置文件

maven_user.properties配置文件主要是配置了Maven私服上的Release版本、Beta版本、Dev版本的仓库,以及用户名和密码等基本配置。如下所示

这里写图片描述

代码如下所示:

#用户名
repository.user=androidcsdn

#密码
repository.password=ouyangpengcsdn

#release仓库地址
repository.url.release=http://172.28.10.222:8081/nexus/content/repositories/android-release/

#beta仓库地址
repository.url.beta=http://172.28.10.222:8081/nexus/content/repositories/android-beta/

#dev仓库地址
repository.url.dev=http://172.28.10.222:8081/nexus/content/repositories/android-dev/

2.3 maven_pom.properties配置文件

maven_pom.properties配置文件主要是配置了要打包生成后的AAR包上传到Maven私服之后的一些Maven属性,主要包括groupId属性,artifactId属性,version属性,type属性等,代码如下。

这里写图片描述


POM_NAME=android

POM_DESCRIPTION=a lib for ouyangpeng

#对应Maven groupId
POM_GROUP=com.xtc.ouyangpeng

#对应Maven aritfaceId
POM_ARTIFACT_ID=ouyangpeng
#打包方式
POM_PACKAGING=aar

#RELEASE版本
POM_VERSION_RELEASE=0.0.1
#DEV版本
POM_VERSION_DEV=0.0.2-Dev
#BETA版本
POM_VERSION_BETA=0.0.1-Beta

#类型分为 DEV、BETA、RELEASE 三种
POM_VERSION_TYPE=DEV

如上图所示的配置,我们这次要上传的版本为DEV版本,这样我会上传POM_VERSION_DEV=0.0.2-Dev到
dev仓库地址repository.url.dev
http://172.28.10.222:8081/nexus/content/repositories/android-dev/

如果想上传Beta版本的,则将POM_VERSION_TYPE属性改为BETA ,并修改属性POM_VERSION_BETA为你想上传的版本号,如改为如下的配置:

#RELEASE版本
POM_VERSION_RELEASE=0.0.1
#DEV版本
POM_VERSION_DEV=0.0.2-Dev
#BETA版本
POM_VERSION_BETA=0.0.5-Beta
#类型分为 DEV、BETA、RELEASE 三种
POM_VERSION_TYPE=BETA

则说明你要将Beta版本的版本号为0.0.5-Beta的AAR上传到
Beta仓库地址repository.url.beta
http://172.28.10.222:8081/nexus/content/repositories/android-beta/

之后想上传不同的版本到不同的仓库的话,只需要修改该文件的POM_VERSION_TYPE属性以及相应版本的版本号属性,如POM_VERSION_RELEASE对应的Release版本,POM_VERSION_DEV对应的Dev版本,POM_VERSION_BETA对应的Beta版本。

之后其他的配置文件maven_user.properties配置文件和maven_upload.gradle文件不需要修改,只需要修改该配置文件即可根据不同的类型上传到不同的仓库。


作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:
http://blog.csdn.net/ouyang_peng/article/details/56872556

这里写图片描述


三、执行上传maven的gradle脚本文件

第一步点击右边的侧边栏 Gradle选项,第二步选中uploadArchives任务,
这里写图片描述

第二步点击鼠标右键,选中第一项 Run ,执行上传gradle脚本 ,如下图所示
这里写图片描述

#RELEASE版本
POM_VERSION_RELEASE=0.0.1
#DEV版本
POM_VERSION_DEV=0.0.2-Dev
#BETA版本
POM_VERSION_BETA=0.0.5-Beta

#类型分为 DEV、BETA、RELEASE 三种
POM_VERSION_TYPE=BETA

3.1 上传成功

例如上面我们上次版本为0.0.5-Beta的版本到Beta仓库,执行脚本之后,如果一切正常的话,Android Studio的Run窗口可以看到如下所示的提示:

这里写图片描述

点击左上角的漏斗标志,可以看到一片绿色。
这里写图片描述

这里写图片描述

就会在Nexus服务器(http://172.28.10.222:8081/nexus/#view-repositories) 上可以查看上传的具体内容,如下所示:

这里写图片描述

点开可以查看上次的具体内容,如下图所示:
这里写图片描述

<dependency>
  <groupId>com.xtc.ouyangpeng</groupId>
  <artifactId>ouyangpeng</artifactId>
  <version>0.0.5-Beta</version>
  <type>aar</type>
</dependency>

这里写图片描述

3.2 上传失败

因为坚持一个约定优于配置原则,因此我们团队内部有了如下的约定,并且要求大家严格按照约定来填写配置文件,约定如下所示。

RELEASE版本,不需要后缀
POM_VERSION_RELEASE=0.0.1

DEV版本,后缀为Dev
POM_VERSION_DEV=0.0.2-Dev

BETA版本,后缀为Beta
POM_VERSION_BETA=0.0.6-Beta

类型分为 DEV、BETA、RELEASE 三种,也仅有此三种情况。
POM_VERSION_TYPE=DEV

但是难免会有人不按照约定来,因此我在maven_upload.gradle文件文件中,读取maven_pom.properties配置文件和maven_user.properties配置文件的内容之后,会有相关的逻辑来判断配置的是否符合规范,如果不符合规范的话,则会抛异常提醒团队成员配置出错了。

例如我们将maven_pom.properties的部分配置配置如下所示,故意将POM_VERSION_TYPE配置为错误的BETAa,正确的只能是DEV、BETA、RELEASE 三种


POM_NAME=android

POM_DESCRIPTION=a lib for ouyangpeng

#对应Maven groupId
POM_GROUP=com.xtc.ouyangpeng

#对应Maven aritfaceId
POM_ARTIFACT_ID=ouyangpeng
#打包方式
POM_PACKAGING=aar

#RELEASE版本
POM_VERSION_RELEASE=0.0.1
#DEV版本
POM_VERSION_DEV=0.0.2-Dev
#BETA版本
POM_VERSION_BETA=0.0.5-Beta

#类型分为 DEV、BETA、RELEASE 三种
POM_VERSION_TYPE=BETAa

这里写图片描述

因此就会报错,提示如下所示:
这里写图片描述

20:13:05: Executing external task 'uploadArchives'...
Configuration on demand is an incubating feature.
Incremental java compilation is an incubating feature.
Failed to notify ProjectEvaluationListener.afterEvaluate(), but primary configuration failure takes precedence.
java.lang.IllegalStateException: buildToolsVersion is not specified.
    at com.google.common.base.Preconditions.checkState(Preconditions.java:173)
    at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:645)
    at com.android.build.gradle.BasePlugin$10.call(BasePlugin.java:608)
    at com.android.build.gradle.BasePlugin$10.call(BasePlugin.java:605)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:156)
    at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:120)
    at com.android.build.gradle.BasePlugin.lambda$createTasks$1(BasePlugin.java:603)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:93)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:82)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy11.afterEvaluate(Unknown Source)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:67)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:61)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:540)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:93)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:47)
    at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:84)
    at org.gradle.execution.TaskSelector.getSelection(TaskSelector.java:75)
    at org.gradle.execution.commandline.CommandLineTaskParser.parseTasks(CommandLineTaskParser.java:42)
    at org.gradle.execution.TaskNameResolvingBuildConfigurationAction.configure(TaskNameResolvingBuildConfigurationAction.java:44)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:48)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:25)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:54)
    at org.gradle.execution.DefaultTasksBuildExecutionAction.configure(DefaultTasksBuildExecutionAction.java:44)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:48)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.access$000(DefaultBuildConfigurationActionExecuter.java:25)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter$1.proceed(DefaultBuildConfigurationActionExecuter.java:54)
    at org.gradle.execution.ExcludedTaskFilteringBuildConfigurationAction.configure(ExcludedTaskFilteringBuildConfigurationAction.java:47)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.configure(DefaultBuildConfigurationActionExecuter.java:48)
    at org.gradle.execution.DefaultBuildConfigurationActionExecuter.select(DefaultBuildConfigurationActionExecuter.java:36)
    at org.gradle.initialization.DefaultGradleLauncher$3.run(DefaultGradleLauncher.java:142)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:139)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
    at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:46)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:58)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

FAILURE: Build failed with an exception.

* Where:
Script 'C:\Code\MavenTest\ouyangpeng\maven_upload.gradle' line: 42

* What went wrong:
A problem occurred evaluating script.
> Could not find method Exception() for arguments [>>>>>>>>>>>>>>上传失败,POM_VERSION_TYPE = BETAa ,请确认maven_user.properties文件中 POM_VERSION_TYPE 参数填写正确,POM版本必须为(DEV、BETA、RELEASE)中的一种类型<<<<<<<<<<] on task ':ouyangpeng:uploadArchives' of type org.gradle.api.tasks.Upload.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 4.096 secs
20:13:09: External task execution finished 'uploadArchives'.

提示我们 maven_upload.gradle’ 文件 42 行抛了异常,异常提醒为:

>>>>>>>>>>>>>>上传失败,POM_VERSION_TYPE = BETAa ,请确认maven_user.properties文件中 POM_VERSION_TYPE 参数填写正确,POM版本必须为(DEV、BETA、RELEASE)中的一种类型<<<<<<<<<<

maven_upload.gradle’ 文件 42 行代码如下图所示:

这里写图片描述

因此,只要我们将POM_VERSION_TYPE配置为正确的只能是DEV、BETA、RELEASE 三种中的一种,即可正常上传成功。

还有一种可能出错的地方是用户名和密码配置出错了,也会报错,错误如下所示:

Error:Execution failed for task ':ouyangpeng:uploadArchives'.
> Could not publish configuration 'archives'
   > Failed to deploy artifacts: Could not transfer artifact com.xtc.ouyangpeng:ouyangpeng:aar:0.0.5-Beta from/to remote (http://172.28.10.222:8081/nexus/content/repositories/android-beta/): Failed to transfer file: http://172.28.10.222:8081/nexus/content/repositories/android-beta/com/xtc/ouyangpeng/ouyangpeng/0.0.5-Beta/ouyangpeng-0.0.5-Beta.aar. Return code is: 401, ReasonPhrase: Unauthorized.

这里写图片描述

这儿提示是因为我们的用户名和密码填写错误了,或者是该用户名并不能在该仓库中上传文件之类的,总之配置好正确的用户名和密码之后,就可以上传成功了。


四、使用maven私服中的库文件

这里写图片描述
如上图所示,我们已经将模块ouyangpeng打包成aar并上传到了Maven私服,现在我们在模块app中使用刚才上传好的库文件。

4.1 配置工程根目录下的 build.gradle 文件

先在工程根目录下的 build.gradle 文件中 repositories (2个都要)添加如下代码片段:

maven { url "http://172.28.10.222:8081/nexus/content/groups/android_public/" }

配置完成之后的完整代码如下所示:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        maven { url "http://172.28.10.222:8081/nexus/content/groups/android_public/" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'

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

allprojects {
    repositories {
        jcenter()
        maven { url "http://172.28.10.222:8081/nexus/content/groups/android_public/" }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

这里写图片描述

至于为什么是配置 http://172.28.10.222:8081/nexus/content/groups/android_public/ 这个地址的话,是因为我将Beta/Dev/Release仓库都使用android public 仓库来映射了,只要访问android public 仓库就可以顺利的访问Beta/Dev/Release仓库,如下图所示:

这里写图片描述

点击可以查看刚才上传好的Beta/Dev/Release版本的开发库,如下图所示
这里写图片描述

这里写图片描述

4.2 配置 app module中的build.gradle 文件

在app模块的build.gradle 文件中添加如下依赖。

dependencies {
    compile 'com.xtc.ouyangpeng:ouyangpeng:0.0.5-Beta'
}

配置完之后的完整代码如下所示:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"
    defaultConfig {
        applicationId "com.xtc.maven.test"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.0'
    compile 'com.android.support:design:25.0.0'
    testCompile 'junit:junit:4.12'

    compile 'com.xtc.ouyangpeng:ouyangpeng:0.0.5-Beta'
}

这里写图片描述

然后重新同步编译一下,编译成功之后,可以看到如下所示的引用包中包含了刚才的ouyangpeng:0.0.5-Beta.aar

这里写图片描述

点开可以查看源代码如下所示,可以发现有注释。
这里写图片描述

package test.maven.xtc.com.ouyangpeng;

/**
 * 测试上传Android开发库AAR文件到Maven私服
 * </p>
 * created by OuyangPeng at 2017/2/24 19:06
 *
 * 博客地址:http://blog.csdn.net/ouyang_peng/
 */
public class MavenTest {
    /**
     * 测试Maven注释
     */
    private String mMaven = "maven";

    public String getMaven() {
        return mMaven;
    }

    public void setMaven(String maven) {
        mMaven = maven;
    }
}

如果引用一个Release版本的,则没有注释,如下所示:
重新上传一个RELEASE版本的aar到Maven私服,配置文件如下

#RELEASE版本
POM_VERSION_RELEASE=0.0.1
#DEV版本
POM_VERSION_DEV=0.0.2-Dev
#BETA版本
POM_VERSION_BETA=0.0.5-Beta

#类型分为 DEV、BETA、RELEASE 三种
POM_VERSION_TYPE=RELEASE

上传成功后,如下所示:
这里写图片描述

现在在工程中引用该ouyangpeng:0.0.1.aar版本的AAR文件,更改build.gradle的引用配置为

dependencies {
    compile 'com.xtc.ouyangpeng:ouyangpeng:0.0.1'
}  

这里写图片描述

现在打开ouyangpeng:0.0.1.aar的源代码查看,发现没有注释,如下所示:
这里写图片描述


//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package test.maven.xtc.com.ouyangpeng;

public class MavenTest {
    private String mMaven = "maven";

    public MavenTest() {
    }

    public String getMaven() {
        return this.mMaven;
    }

    public void setMaven(String maven) {
        this.mMaven = maven;
    }
}

至于这三个版本Release版本、Beta版本、Dev版本的仓库如何新建,我准备在下一篇博客再写。

作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:
http://blog.csdn.net/ouyang_peng/article/details/56872556

这里写图片描述

相关文章
|
16天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
40 19
|
16天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
41 14
|
19天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
17天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
30 5
|
16天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
17天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
17天前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
20天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
17天前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
24 0
|
20天前
|
存储 监控 Java
探索安卓开发:从基础到进阶的旅程
在这个数字时代,移动应用已成为我们日常生活的一部分。对于开发者来说,掌握安卓开发不仅是技能的提升,更是通往创新世界的钥匙。本文将带你了解安卓开发的核心概念,从搭建开发环境到实现复杂功能,逐步深入安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的见解和技巧,帮助你在安卓开发的道路上更进一步。
20 0