打包时添加内容脚本插件

####需求:为每次打包生成内容数据信息

Gradle自定义插件有三种方式:https://zhuanlan.zhihu.com/p/158588813

1. 在build.gradle

直接在app目录下的build.gradle文件中写

1
2
3
4
5
6
7
8
9
10
11
class MyPlugin implements Plugin<Project>{
@Override
void apply(Project target) {
println('MyPlugin执行了')
target.task("mytask"){
doLast {
println('MyPlugin中的task执行了')
}
}
}
}

然后在

app的build.gradle文件中引入插件:

apply plugin: MyPlugin

然后再控制台输入gradlew mytask

1
2
3
4
5
> Configure project :app
MyPlugin执行了

> Task :app:mytask
MyPlugin中的task执行了

使用这种方式可以很快的创建一个插件,缺点就是只能在当前的build.gradle使用,复用差。

2. 在buildSrc文件夹下

buildSrc是Gradle中的默认插件目录,编译的时候Gradle会自动识别这个目录,将其内的代码编译撑成插件。

在根目录新建一个文件叫buildSrc,然后在buildSrc文件新建build.gralde文件写入代码:

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
apply(plugin = "kotlin")
apply(plugin = "java")

buildscript {
repositories {
maven("https://maven.aliyun.com/repository/gradle-plugin")
maven("https://maven.aliyun.com/repository/central")
google()
}

dependencies {
classpath("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.20")
}
}

allprojects {
repositories {
maven("https://maven.aliyun.com/repository/gradle-plugin")
maven("https://maven.aliyun.com/repository/central")
google()
}
}

dependencies {
// 引入源代码
implementation("com.android.tools.build:gradle:4.2.2")
}

build.gradle文件内容写完后我们同步下功能,就可以在buildSrc文件里面看到文件.gradle和build这两个文件。现在我们在buildSrc下面新建文件src/main/groovy 和 src/main/resources/META-INF/gradle-plugins。

img1

然后在groovy文件加里新建我们的插件MyPlugin.groovy

1
2
3
4
5
6
7
8
9
10
11
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project target) {
println('buildSrc中MyPlugin执行了')
target.task("mytask"){
doLast {
println('buildSrc中MyPlugin中的task执行了')
}
}
}
}

写完插件怎么让编译器知道这是我们的插件呢?

  • 在main目录下的resources/META-INF/gradle-plugins目录新建propertites文件
  • properties文件的名字就是我们在build.gradle里面通过apply引入时候要写的名字,通常都是使用报名。com.yu.releaseInfo。然后文件内容写:implementation-class= com.yu.releaseInfo.MyPlugin

然后在app的build.gradle里面映入插件:

1
apply plugin :'com.yu.releaseInfo'

最后在控制台进行测试:

1
2
3
4
5
> Configure project :app
buildSrc中MyPlugin执行了

> Task :app:mytask
buildSrc中MyPlugin中的task执行了

第三种上传maven

上传maven这样所有人都可以使用咱么这个项目了。

可以参考我的另外一篇博客。 Gradle上传插件到仓库


进行实战

这里我们使用第二种方式,在buildSrc里面写我们的插件。

在groovy文件夹新建类 1. ReleaseInfoExtension.groovy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ReleaseInfoExtension {
String versionCode
String versionName
String versionInfo
String fileName
String afterTask = "assembleDebug"

ReleaseInfoExtension() {

}

@Override
String toString() {
"""
versionCode = ${versionCode}
versionName = ${versionName}
versionInfo = ${versionInfo}
fileName = ${fileName}
afterTask = ${afterTask}
"""
}
}

我们把我们的基础信息放在类里面。

2. 新建插件类ReleaseInfoPlugin.groocy

这个类用来创建我们的扩展参数和扩展方法,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.gradle.api.Plugin
import org.gradle.api.Project

// 打包的数据 插件
class ReleaseInfoPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
// 为工程添加扩展参数 releaseInfoYu 他的具体实现类是ReleaseInfoExtension
ReleaseInfoExtension releaseInfoExtension = project.extensions.create('releaseInfoYu', ReleaseInfoExtension)
// 为工程创建额外的task 名字叫releaseInfoTask 具体实现类ReleaseInfoTask
ReleaseInfoTask releaseInfoTask = project.tasks.create('releaseInfoTask', ReleaseInfoTask)
// 这一步骤是为了把我们自定义的releaseInfoTask添加到打包的task的之后自动执行
project.afterEvaluate {
project.tasks.findByName(releaseInfoExtension.afterTask).finalizedBy(releaseInfoTask)
}

}
}

然后在resources/META-INF/gradle.plugins 下新建文件 releaseinfo.properties。内容:

1
implementation-class=ReleaseInfoPlugin

同步下工程。

3. 在app的build.gradle引入我们的插件

apply plugin :’releaseinfo’

4. 配置打包信息

1
2
3
4
5
6
7
8
releaseInfoYu { re ->
project.getExtensions().android.applicationVariants.all { variant ->
re.versionCode = variant.getVersionCode()
re.versionName = variant.getVersionName()
}
versionInfo = "第一次提交的版本数据"
fileName = "release.xml"
}

注意我们首先要在app目录下新建一个空白文件release.xml

5. 完成写入xml的task任务

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
import groovy.xml.MarkupBuilder
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction

import java.text.SimpleDateFormat

class ReleaseInfoTask extends DefaultTask{
ReleaseInfoTask(){
group = "libertyYu"
description = "update the release info"
}

@TaskAction
void doAction(){
updateInfo()
}

void updateInfo(){
String versionCodeMsg = project.extensions.releaseInfoYu.versionCode
String versionNameMsg = project.extensions.releaseInfoYu.versionName
String versionInfoMsg = project.extensions.releaseInfoYu.versionInfo
String fileName = project.extensions.releaseInfoYu.fileName
StringWriter stringWriter = new StringWriter()
MarkupBuilder xmlBuilder = new MarkupBuilder(stringWriter)
def file = project.file(fileName)
if (file == null && !destFile.exists()) {
file.createNewFile()
}
Date currentTime = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(currentTime);

if (file.text != null && file.text.size() <= 0) {
//没有内容
xmlBuilder.releases {
release {
versionCode(versionCodeMsg)
versionName(versionNameMsg)
versionInfo(versionInfoMsg)
versionTime(dateString)
}
}
//直接写入
file.withWriter { writer -> writer.append(stringWriter.toString())
}
} else {
//已有其它版本内容
xmlBuilder.release {
versionCode(versionCodeMsg)
versionName(versionNameMsg)
versionInfo(versionInfoMsg)
versionTime(dateString)
}
//插入到最后一行前面
def lines = file.readLines()
def lengths = lines.size() - 1
file.withWriter { writer ->
lines.eachWithIndex { line, index ->
if (index != lengths) {
writer.append(line + '\r\n')
} else if (index == lengths) {
writer.append('\r\r\n' + stringWriter.toString() + '\r\n')
writer.append(lines.get(lengths))
}
}
}
}
}

}

测试

执行我们的assembleDebug任务后可以在release.xml文件看到如下内容:

1
2
3
4
5
6
7
8
<releases>
<release>
<versionCode>2</versionCode>
<versionName>1.0</versionName>
<versionInfo>第一次提交的版本数据</versionInfo>
<versionTime>2021-10-06 08:44:43</versionTime>
</release>
</releases>