Android Settings,SourceSet,自定义Plugin

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tʀᴜsᴛ³⁴⁵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值