####需求:为每次打包生成内容数据信息
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。
然后在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) { ReleaseInfoExtension releaseInfoExtension = project.extensions.create('releaseInfoYu', ReleaseInfoExtension) ReleaseInfoTask releaseInfoTask = project.tasks.create('releaseInfoTask', ReleaseInfoTask) 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>
|