利用Android Gradle进行自动化设置资源名命名规则

一、背景描述:

    公司再不断推进组件化,多个Module开发。随着Module越来越多,当然也存在许多需要注意的问题。是无法保证多个Module中的资源命名完全不同,就可能会出现资源引用问题,造成资源冲突。

二、思路分析

     用Gradle配置,在android 中设置 resourcePrefix 属性,前缀字符串根据实际情况自定义。
     但是因为Module太多,每添加一个模块就需要在Modulebuild.gradle里进行配置, 这样太繁琐,不够智能,那么怎么解决呢,思路如下:

     1、写一个Task,生成一个json文件,里面以key->value的形式存储模块名和其对应的前缀。

     2、将json文件中前缀value进行修改,每次task执行更新不会覆盖之前修改过的value,默认前缀名是模块名。

     3、在所有模块Gradle都配置完之后,给每个模块设置一下修改后的前缀属性

效果展示:

    编译器会这样提示,但是编译的时候不会报错在这里插入图片描述

三、问题解决与实现

步骤1:写一个更新/生成命名json文件的task
    这个task我们暂时写到 appbuild.gradle文件中,写在别的.gradle文件中也可以

task moduleNameToJson() {

    doLast {
        def jsonFile = file('./ResourceNameRule.json')
        def mapResult = new HashMap<String, String>()
        // 每次新建的module不会覆盖之前修改过的value
        if (jsonFile.exists()){
            def parsedJson = new JsonSlurper().parseText(jsonFile.text)
            parsedJson.each {
                mapResult.put(it.key.toString(), it.value.toString())
            }
            mapResult = loopGetName(mapResult, rootProject)
        }else{
            mapResult = loopGetName(null, rootProject)
        }
        println mapResult.toString()
        try{
            def  writer = new FileWriter("./app/ResourceNameRule.json")
            def  gson = new Gson().newBuilder().create()
            gson.toJson(mapResult, writer)
            writer.flush()
            writer.close()
        }catch (Exception e) {}
    }

}

/**
 * 给所有模块名处理命名
 *
 * @param hashmap 有json文件就传入旧map
 * @param project 执行时期的功能
 * @return HashMap
 */
private static HashMap<String,String> loopGetName(HashMap<String, String> hashmap, Project project){
    def map
    if(hashmap!=null){
        map = hashmap
    }else{
        map = new HashMap<String, String>()
    }

    project.allprojects {
        def childAndroid = null
        try {
            childAndroid = it.extensions.getByType(AppExtension.class)
        } catch (Exception e) {}
        try {
            if (childAndroid == null) {
                childAndroid = it.extensions.getByType(LibraryExtension.class)
            }
        } catch (Exception e) {}
        if (childAndroid != null)  {
        // module命名 最好以module_XXX 这样,这里可以自己对模块名进行处理
            def prefix = "${it.name}".replace("module_", "")
            if (hashmap == null){
                if (prefix != null){
                    map.put(it.name, prefix)
                }
            }else{
                if (map.get(it.name) == null || map.get(it.name) == ""){
                    map.put(it.name, prefix)
                }
            }
        }
    }
    return map
}

步骤二: 把json文件进行修改
在这里插入图片描述
步骤三: 点击sync时,将前缀属性设置到每个Module中

Hook点:
在这里插入图片描述
Gradle构建周期中的Hook点
                                                Gradle构建周期中的Hook点

    要给每个module都设置属性就要考虑Gradle执行的生命周期了,不然获取到也是空的。这里我们选择在gradle.afterProject时期进行hook,读取配置好的json文件,给每个Module设置前缀规则,这个我们也暂时写到app的build.gradle中,代码如下:

gradle.afterProject {
    // 获取资源命名规则的配置文件
    def jsonFile = file('./ResourceNameRule.json')
    if (jsonFile.exists()){
        def parsedJson = new JsonSlurper().parseText(jsonFile.text)
        rootProject.allprojects {
            def childAndroid = null
            try  {
                childAndroid = it.extensions.getByType(AppExtension.class)
            } catch (Exception e) {
            }
            try {
                if (childAndroid == null) {
                    childAndroid = it.extensions.getByType(LibraryExtension.class)
                }
            } catch (Exception e) {
            }
            try {
                if (childAndroid != null) {
                    parsedJson.each { entry ->
                    // 这里可以对模块进行过滤
                        if ("libMatisse" == entry.key.toString()){
                            return
                        }
                        if (entry.key.toString() == it.name) {
                            childAndroid.resourcePrefix(entry.value.toString())
                        }

                    }
                }
            } catch (Exception e) {
                childAndroid = null
                return
            }
        }
    }
}

四、工具的使用

1、每次添加新Module之后,先运行task,生成新的json文件或者更新 新的模块到json文件中。
在这里插入图片描述
2、把json文件中的前缀修改成你想要的前缀
3、点击大象,sync一下,就全局设置啦
在这里插入图片描述

五、结论与展望

     如此就可以进行自动化设置资源名的前缀属性,前缀字符串也可以动态配置,非常的方便。随着模块越来越多,这样做的效果只会越来越明显,不按照规则起名字不会导致编译报错,但是资源名重复会导致编译报错。规范命名总是好的。

     但项目也有点小缺陷,目前是将代码写到了app下的build.gradle里,导致该文件代码比较多。未来可以优化,单独建一个.gradle文件进行封装,大佬们提提思路,现在遇到的问题是Gson不能在其他的.gradle中使用。代码写的也比较冗余,还不够精简,进步的空间还挺大,加油,奥里给!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值