Settings 类
决定一个工程中有哪些模块是需要被处理的。
public interface Settings extends PluginAware, ExtensionAware {
//默认的文件名称
String DEFAULT_SETTINGS_FILE = "settings.gradle";
//将指定的 project 加载到的构建中
void include(String... projectPaths);
}
Settings 类如何被 gradle 初始化完全取决于 settings.gradle 文件的配置。setting.gradle 中就需要指定有哪些模块需要被处理。
include ':app', ':core', ':detegateManager', ':tabHome', ':tabShop', ':tabDiscover', ':tabMall', ':tabMine', ':ui'
如上就是有多个模块被加载到构建中,Settings 会在 gradle 生命周期的初始化阶段执行,确定要构建的模块,并创建 project 对象
SourceSet 类
gradle 是如何从从 src/main/java/package/ 下面去读取我们的源码,然后生成字节码文件呢?其实就是通过 SourceSet 类的配置中拿到的。
SourceSet 类决定了我们所有的代码,资源,第三方库等存放的位置。
gradle 中约定大于配置,只要没有配置,那就是按约定的来。gradle 默认从 java 文件下获取源码,从 res 文件下获取资源 进行编译。这些约定可以进行修改。
通过 SourceSet 类我们可以修改默认的存放路径,如 so 的路径,res 的路径,java 文件的路径等。如下所示:
android {
sourceSets {
main {
//修改 so 文件存放的位置
jniLibs.srcDirs = ['libs']
}
}
}
使用上面的配置后,gradle 在加载 so 文件时就会从 libs 下进行加载。
修改资源路径:如果一个项目太过庞大,其代码还可以通过创建 package 来整理一下,看起来会更加简洁,容易寻找。但是资源文件却不行,默认只有一个 res 目录,所有的自愈都需要放在 res 中。但是通过 SourceSet 类可以指定多个 res 文件夹,这些文件夹里面就可以存放不同模块下的资源文件了。如下:
在 main 文件下新建文件夹 res-ad 用来存放广告资源,res-play 存放游戏资源。创建完成后在 build.gradle 中的 android 下添加如下代码:
sourceSets {
main {
res.srcDirs = ['src/main/res',
'src/main/res-ad',
'src/main/res-play']
}
}
接着同步一下,就会发现这两个文件夹上面的图标和 res 的图标是一样的了。
Plugin 详解及自定义 Plugin
Gradle 插件使用 Groovy 开发的,而 Groovy 完全兼容 Java ,使用 AS 完全可以开发 Gradle 插件。
处理插件:Gradle 会自动找到插件的所在位置,如 buildSrc 名字会被 Gradle 识别为 插件工程
应用环境:一旦插件被应用到构建的脚本中,那么插件对应的 apply 方法就会被调用
插件项目的创建:在 as 中新建一个 library。删除一些内容。使其和图片中的一样:
groovy 下新建一个包名。
META-INF/gradle-plugins/下新建一个 .properties 文件,这里的为文件名字最终会出现在:
apply plugin: 'com.car.srcplugin'
注意 :build.gradle 中所有的内容都需要删掉
下面开始一个小 Demo:还是保存每次发布的版本信息。只不过有了很大的改进。
1,配置一些 build.gradle
apply plugin: 'groovy'
sourceSets {
main {
groovy {
srcDir 'src/main/groovy'
}
resources {
srcDir 'src/main/resources'
}
}
}
dependencies {
//gradle sdk
implementation gradleApi()
//groovy sdk
implementation localGroovy()
}
2,自定义 Taks
class UpDataInfoTask extends DefaultTask {
private VersionInfo versionInfo
ReleaseInfoTask() {
//设置组名和描述信息
group = '345'
description = 'update the release info'
}
/**
* 使用 TaskAction 注解,这个方法会执行在执行阶段
* doFirst 就是给这个方法的最前面添加代码
* doLast 就是给这个方法的最后面添加代码
*/
@TaskAction
void doAction() {
upDataInfo()
}
/**
* 将 Extension 类中的信息写入到指定的文件中
*/
void upDataInfo() {
project.logger.error "------------------- 开始插入信息 -------------------"
String versionNameMsg = project.extensions
.upDataInfo.versionName
String versionCodeMsg = project.extensions
.upDataInfo.versionCode
String versionInfoMsg = project.extensions
.upDataInfo.versionInfo
String buildType = project.extensions.
upDataInfo.buildType
if (buildType == null || buildType.isEmpty()) {
buildType = "Release"
}
File file = project.file(buildType + ".json")
if (file != null && !file.exists()) {
file.createNewFile()
}
if (file.text != null && file.text.size() >= 0) {
String text = file.text
if (text != null && !text.isEmpty()) {
versionInfo = new JsonSlurper().parseText(text)
} else {
versionInfo = new VersionInfo()
versionInfo.setUpDataInfo = []
}
if (versionInfo.setUpDataInfo.size() > 0) {
//如果版本号一样,使用新的
int pos = versionInfo.setUpDataInfo.size() - 1;
if (versionNameMsg == versionInfo.setUpDataInfo.get(pos).versionName) {
project.logger.error "------------------- 版本号相同,已替换 -------------------"
versionInfo.setUpDataInfo.remove(pos)
}
}
VersionInfo.UpDataInfoBean bean = new VersionInfo.UpDataInfoBean();
bean.versionCode = versionCodeMsg
bean.versionName = versionNameMsg
bean.versionInfo = versionInfoMsg
bean.versionTime = stampToDate(System.currentTimeMillis())
versionInfo.setUpDataInfo.add(bean)
String json = JsonOutput.toJson(versionInfo)
file.withWriter {
write ->
write.write(JsonOutput.prettyPrint(json))
}
project.logger.error "------------------- 更新信息已生成 -------------------"
}
}
private static String stampToDate(long time) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date(time)
simpleDateFormat.format(date)
}
}
3,VersionInfo
class VersionInfo {
private List<UpDataInfoBean> updataInfo;
public List<UpDataInfoBean> getSetUpDataInfo() {
return updataInfo;
}
public void setSetUpDataInfo(List<UpDataInfoBean> relaseInfo) {
this.updataInfo = relaseInfo;
}
public static class UpDataInfoBean {
/**
* versionName :
* versionCode :
* versionInfo :
* versionTime :
*/
private String versionName;
private String versionCode;
private String versionInfo;
private String versionTime;
public String getVersionName() {
return versionName;
}
public void setVersionName(String versionName) {
this.versionName = versionName;
}
public String getVersionCode() {
return versionCode;
}
public void setVersionCode(String versionCode) {
this.versionCode = versionCode;
}
public String getVersionInfo() {
return versionInfo;
}
public void setVersionInfo(String versionInfo) {
this.versionInfo = versionInfo;
}
public String getVersionTime() {
return versionTime;
}
public void setVersionTime(String versionTime) {
this.versionTime = versionTime;
}
}
}
4,UpDataInfoExtension
闭包中要用到的属性
class UpDataInfoExtension {
/**
* code
*/
String versionCode
/**
* name
*/
String versionName
/**
* 发布信息
*/
String versionInfo
/**
* 打包类型。默认为 Release ,也可以是 Debug。注意 首字母大写。
*/
String buildType
}
5,自定义 plugin
/**
* 自定义插件
*/
class GradleStudyPlugin implements Plugin<Project> {
Project mProject = null;
/**
* 插件被引入时要执行的方法
* @param project 引入当前插件的 project
*/
@Override
void apply(Project project) {
mProject = project
def android = mProject.extensions.android
//通过在外边定义 upDataInfo 闭包,完成对 UpDataInfoExtension 的初始化
project.extensions.create('upDataInfo', UpDataInfoExtension)
//创建 Task
UpDataInfoTask task = project.tasks.create('upDataInfoTask', UpDataInfoTask)
//配置阶段完成后执行
mProject.afterEvaluate {
String buildType = mProject.extensions.upDataInfo.buildType
//默认 Release
if (buildType == null || buildType.isEmpty()) {
buildType = "Release"
}
mProject.logger.error("------------------- ${buildType} -------------------")
def buildTask = mProject.tasks.getByName("assemble${buildType}")
if (buildTask == null) {
throw GradleException('the build task is not fond')
}
buildTask.doLast {
task.upDataInfo()
}
}
}
}
6,META-INF/gradle-plugins/
META-INF/gradle-plugins/下新建一个 .properties 文件。文件名字一般和包名一样
implementation-class=com.car.srcplugin.GradleStudyPlugin
这里指向自定义的 Plugin
7,使用方式
每次打Release 或者 Debug 包的时候这个会自动执行。或者是使用命令行直接启动也可以。
在 app/build.gradle 中引入
apply plugin: 'com.car.srcplugin'
创建闭包,注意和 android 闭包平级
upDataInfo {
versionCode String.valueOf(version_code)
versionName version_name
versionInfo version_info
//默认 Release,还可以是Debug ,注意首字母大写
buildType "Debug"
}
8,使用结果
9,总结
这个插件也写了好久,因为也是刚开始学,到现在有些问题还没有解决。以后再慢慢解决吧。
android 插件对 gradle 扩展
在 build.gradle 中,有一个 android 的闭包,在这个闭包中可以的定义非常多的内容。BaseExtension 类就是 闭包中能够调用的所有方法如下:
public abstract class BaseExtension implements AndroidConfig {
/** Secondary dependencies for the custom transform. */
private final List<List<Object>> transformDependencies = Lists.newArrayList();
protected final GlobalScope globalScope;
private final DefaultConfig defaultConfig;
private final AaptOptions aaptOptions;
private final LintOptions lintOptions;
private final ExternalNativeBuild externalNativeBuild;
private final DexOptions dexOptions;
private final TestOptions testOptions;
private final CompileOptions compileOptions;
private final PackagingOptions packagingOptions;
private final JacocoOptions jacoco;
private final Splits splits;
......
}
上面列举了部分的属性。android 闭包中所有的属性方法都是调用这个类里面的。
以上就是全部内容,如有问题,可直接评论或者私信,一起学习交流。我也是刚开始学习gradle