玩转 Gradle,Plugin本质是什么?剖析个知名插件
本文作者
作者:CoderPig
链接:
https://juejin.cn/post/6956517422606057479
本文由作者授权发布。
关于 Gradle 的学习,我所理解的流程如下:
1. 了解 Gradle 的本质,了解其构建生命周期;
2. 熟悉其内部的核心对象,Projet、Task 等等;
3. 熟悉 Groovy 或者 kotlin,可以自己编写一些简单的 task;
4. 学会自定义 Gradle Plugin;
5. 对Android 打包构建过程中,涉及到的核心 task 分析;
剩下的只有多看了,会在各种开源 plugin 或者博客中看到各种小技巧,然后在不断的「还能这么写?」「我*,这也可以」「可以,学到了」中成长,增加个人解决问题的技巧与方式。
本文大概属于环节4,对于后续更深入的打包源码分析分享也在路上了,好了看文吧~
Gradle自身并没有提供编译打包的功能,它只是一个负责定义流程和规则的框架,具体的编译工作都是由 插件 来完成的,比如编译Java用Java插件,编译Kotlin用Kotlin插件。插件的本质就是:定义Task,并具体执行这些Task的模板。
https://docs.gradle.org/current/userguide/custom_plugins.html
1. 构建脚本
// 脚本内部访问
def versionName = "v1.0.0"
def versionDesc = "第一个版本"
// 脚本外部访问
ext {
author = "CoderPig"
}
// Task任务
task printVersionInfo {
doLast {
println "$versionName → $versionDesc"
}
}
apply from: 'other.gradle'
task test {
dependsOn(printVersionInfo)
doFirst { println(author) }
doLast { println("build.gradle里的task") }
}
2. buildSrc项目
3. 独立项目
1. 项目组成
package cn.coderpig.plugins
import org.gradle.api.Project
import org.gradle.api.Plugin
publicclassCpPluginPluginimplementsPlugin<Project> {
public void apply(Project project) {
// 注册一个Task
project.tasks.register("greeting") {
doLast {
println("Hello from plugin 'cn.coderpig.plugins.greeting'")
}
}
}
}
// 引用java gradle插件开发插件、kotlin支持
plugins {
id 'java-gradle-plugin'
id 'kotlin'
}
gradlePlugin {
plugins {
greeting {
// 插件id
id = 'cn.coderpig.plugins.greeting'
// 插件实现类
implementationClass = 'cn.coderpig.plugins.CpPluginPlugin'
}
}
}
Tips:网上很多Gradle插件开发教程还要另外配置一个properties文件,如: src/main/resources/META-INF/gradle-plugins/cn.coderpig.plugins.greeting.properties 文件内容如下: implementation-class=cn.coderpig.plugins.CpPluginPlugin 实际上,在build.gradle中声明了gradlePlugin就可以了,无需另外再配置一遍!
2. 插件本地发布
plugins {
// 添加maven插件
id 'maven'
}
uploadArchives {
repositories.mavenDeployer {
repository(url: uri('C:\\Users\\用户名\\Maven\\repo')) // 本地仓库路径
pom.groupId = "cn.coderpig.plugins"// 唯一标识(通常为模块包名,也可以任意)
pom.artifactId = "CpPluginPlugin"// 项目名称(通常为类库模块名称,也可以任意)
pom.version = "0.0.1"// 版本号
}
}
buildscript {
repositories {
...
// 本地Maven地址
maven { url 'C:\\Users\\用户名\\Maven\\repo' }
}
dependencies {
...
// 插件依赖
classpath "cn.coderpig.plugins:cpplugin:0.0.1"
}
plugins {
...
id 'cn.coderpig.plugins.greeting'
}
task("testPlugin") {
group("custom") // 分组,方便找到Task
dependsOn('greeting') // 调用插件里的greeting Task,在执行testPlugin
doLast { println '任务执行完毕' }
}
3. 插件远程发布
① 废弃的JCenter
https://bintray.com/
包括 GoCenter、Bintray、JCenter 在内的多项软件包管理和分发服务都将停止运营。
② Gradle Plugin仓库
https://plugins.gradle.org/docs/submit
https://plugins.gradle.org/docs/publish-plugin
plugins {
...
id "com.gradle.plugin-publish" version "0.14.0"// 上传插件
}
version = "0.0.1"// 自定义插件版本
group = "cn.coderpig.plugins"// 自定义插件分组
// 自定义插件id及实现类
gradlePlugin {
plugins {
greeting {
id = 'cn.coderpig.plugins.greeting'
implementationClass = 'cn.coderpig.plugins.CpPluginPlugin'
}
}
}
// 插件附加信息
pluginBundle {
website = 'https://github.com/coderpig/cpplugin'
vcsUrl = 'https://github.com/coderpig/cpplugin'
description = 'cpplugin gradle plugin'//插件描述
tags = ['cp'] //搜索关键词
plugins {
greeting {
// id会从插件java-gradle-plugin处自动获取
displayName = 'cpplugin gradle plugin'
}
}
}
③ JitPack仓库
https://jitpack.io/
④ mavenCentral仓库
https://issues.sonatype.org/secure/Signup%21default.jspa
https://s01.oss.sonatype.org/
https://juejin.cn/post/6953598441817636900
TestExtension extension = project.getExtensions().create("testExt", TestExtension)
project.extensions.add("testExt", TestExtension)
project.task("TestTask") {
doLast {
//2.获取外界配置的 TestExtension
TestExtension extension = project.testExt
//3.输出插件扩展属性
println ">>>>>>" + extension.message
}
}
testExt {
//给插件扩展的属性赋值
message "helloworld"
}
https://github.com/Meituan-Dianping/walle
https://tech.meituan.com/2017/01/13/android-apk-v2-signature-scheme.html
① 用于写入ID-value信息的Java类库;
② Gradle构建插件用来和Android的打包流程进行结合 ;
③ 用于读取ID-value信息的Java类库;
④ 用于供 com.android.application 使用的读取渠道信息的AAR;
1. GradlePlugin
2. ChannelMaker
PROPERTY_CHANNEL_LIST ↓
channelList.each {generateChannelApk(...) }
PROPERTY_CONFIG_FILE ↓
generateChannelApkByConfigFile(...)
PROPERTY_CHANNEL_FILE ↓
generateChannelApkByChannelFile(...)
configFile instanceof File ↓
generateChannelApkByConfigFile(...)
channelFile instanceof File ↓
generateChannelApkByChannelFile(...)
variantConfigFileName != null
&& variantConfigFileName.length() > 0 ↓
generateChannelApkByConfigFile(...)
3. ChannelWriter
4. PayloadWriter
5. WalleChannelReader
6. ChannelReader
7. PayloadReader
你确定会在 JitPack 上创建依赖库吗?
https://juejin.cn/post/6946377616400220191
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读:
点击 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!