我们清楚知道,几乎所有的软件都是存在一个版本号的东西,APP作为手机上的应用软件也不例外。版本号可以帮助APP升级使用和定位问题。一般地,版本号有3部分构成:主版本号、副版本号 以及 补丁号,例如:1.0.123。也可以是单一个主版本号,格式没有严格要求。
我们在前面的博文《Android Gradle使用详解(三) 之 Android Gradle插件配置详解》中有提到,在Android Gradle中配置版本相关信息主要是给defaultConfig配置块中指定versionCode和verionName两个字段,例如:
android {
……
defaultConfig {
……
versionCode 1
versionName "1.0"
}
}
这种方式最直观,也最粗暴。它存在一个很大的问题,就是当我们的buidl.gradle文件代码越来越多时就会不容易查找,而且一旦只为修改一个版本号而导致出错或版本冲突的代价很高。所以一般我们是不建议这样做的。
还记得我们在前面博文《Android Gradle使用详解(二) 之 项目结构和初识Java Gradle插件》中介绍脚本插件吗?应用脚本插件,其实就是把这个脚本加载进来,它使用的是关键字from,后面紧跟的是一个脚本文件,例如在build.gradle同级目录中新建一个version.gradle文件,内容如下:
ext {
appVersionName = '1.0.0'
appVersionCode = 100
}
然后修改build.gradle内容,在开始时使用apply from加载version.gradle脚本文件,然后为defaultConfig{}的 versionCode和versionName字段指向appVersionName和appVersionCode两个变量:
apply from:'version.gradle'
android {
……
defaultConfig {
……
versionCode appVersionCode
versionName appVersionName
}
}
这样我们把App的版本号和版本名称单独放在一个脚本文件里。以后每次App发版本只需要更改version.gradle文件即可。这种方式的使用比较广泛。
读取属性文件的方法跟脚本插件配置方法很像,也是用一个单独的文件来专门放置版本信息。例如现在在build.gradle同级目录中新建一个versversion.properties文件,内容如下:
VERSION_NAME=1.0.0
VERSION_CODE=100
接着修改build.gradle内容,增加了三个方法,其中getVersionProperty方法就是根据传入的属性值去读取versversion.properties文件对应的内容,另外封装了getAppVersionName和getAppVersionCode方法专门指定版本名称和版本号的对getVersionProperty方法的调用。它们的返回值用变量appVersionName和appVersionCode保存,最后为 defaultConfig{}中的versionCode和versionName字段赋值:
def synchronized getVersionProperty(propName, defValue) {
def file = file("versversion.properties")
def ret = defValue
if (file.exists() && file.canRead()) {
FileInputStream input = new FileInputStream(file)
Properties props = new Properties()
props.load(input)
ret = props.get(propName);
input.close()
}
return ret
}
def getAppVersionName() {
String versionName = getVersionProperty("VERSION_NAME", "0.0.0")
return versionName
}
def getAppVersionCode() {
String versionCodeTxt = getVersionProperty("VERSION_CODE", "000")
int versionCode = versionCodeTxt as Integer
return versionCode
}
def appVersionName = getAppVersionName()
def appVersionCode = getAppVersionCode()
android {
……
defaultConfig {
……
versionCode appVersionCode
versionName appVersionName
}
}
同样的也是把App的版本号和版本名称单独放在一个文件里。以后每次App发版本只需要更改versversion.properties文件即可。目前这种方式的使用也是比较广泛。
在gradle.properties文件中进行配置这个方法也相对比较简单和能使和buidl.gradle文件分离,gradle.properties文件,内容如下:
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
VERSION_NAME=1.0.0
VERSION_CODE=100000
然后修改build.gradle内容:
apply from:'version.gradle'
android {
……
defaultConfig {
……
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION_NAME
}
}
如果你的项目开发是使用gif进行版本控制的话,在每次发布版本时一般情况下都会进行版本分支的创建和打上相应的Tag。这样做的好处就是在新版本的发布的时候能清楚记录版本截止到的功能点,同时也不会因为发布当前版本而停下来,导致影响团队其他人在主干上的继续开发。后续若存在修改BUG等操作再另外同步回主干,这样做是非常便于团队合作。
我们在创建Tag时若是使用版本名称来命名,就可以通过git命令很简单经获得该Tag来作为版本名称。命令如下:
git describe --abbrev=0 -–tags
至于版本号,我们可以通过命令来获取历史所有的Tag数量,这样也刚好每次创建Tag后,版本号就加1,符合版本号的递增逻辑。要获取Tag数量数量可以使用命令:
git tag –-list
清楚思路后后,接下来就是修改build.gradle内容,即定义两个获得版本名称和版本号的方法,然后对versionCode和versionName字段进行指定:
def getAppVersionName() {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'describe', '--abbrev=0', '--tags'
standardOutput = stdout
}
return stdout.toString().replaceAll("\n", "")
}
def getAppVersionCode(){
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git','tag','--list'
standardOutput = stdout
}
return stdout.toString().split("\n").size()
}
def appVersionName = getAppVersionName()
def appVersionCode = getAppVersionCode();
android {
……
defaultConfig {
……
versionCode appVersionCode
versionName appVersionName
}
}
通过这种方式,我们只需要在发布版本打包前,给代码分支创建一个以版本名称作为命名的Tag,然后Android Gradle在打包时就会自动生成应用的版本名称和版本号,不需要修改一行代码非常方便,也不用担心因为写错版本信息而担心。