第六周:gradle学习

应党中央(主席)要求,用代码实现动态指定一个渠道号

首先第一步自定义一个plugin

class mPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {

        }
    }
}

然后根据我们的需求我们需要拿到manifest文件,并动态更改其中的channel节点

所以我们可以先给channel赋值:<meta-data android:name="channel" android:value="channelValue" />

channelValue就是我们的坑位,需要在gradle里更改manifest文件,最先想到的就是将文件变为string,然后替换(replace)掉“channelValue”,于是有了下面的代码:

void apply(Project project) {
        project.afterEvaluate {
            //拿到manifest文件
            File manifest = new File("app/src/main/AndroidManifest.xml")
            //转换为String
            String mText = manifest.text
            //替换坑位
            String replaceText = mText.replaceAll("channelValue", project.channel)
            写进manifest文件里(groovy写法,超级方便)
            manifest.write(replaceText)
            }
        }

so easy妈妈再也不用担心我的学习!~(其实之前还试过XML解析,IO读写都失败了)不过通过学习,了解了groovy的IO操作和XML解析,比JAVA方便的多,大家有兴趣可以了解下。

assembleRelease一波后发现完美执行,我的manifest文件变成了这样:

<meta-data android:name="channel" android:value="1001" />

好了,文本到此结束.......个屁啊,manifest文件变成这样了,下次构建的时候坑位“channelValue”不就没有了吗?难道手动改,那gradle的意义何在?

想想manifestPlaceholders的实现,只在APK的manifest里更改了相应的渠道变量,而工程里的没有变。如何实现呢?

1、找到gradle打包时的manifest,更改此文件的内容

2、先改掉,打包完成后又改回来

第一种实现方式恕在下愚笨,没有找到(没有源码真的好难做)

于是选择了第二种方式,那么难点来了:代码如何在打包或者manifest使用后执行呢?学习了刚哥一波视频后知道了assembleRelease依赖了很多任务,从中我找到了manifest相关的任务:processReleaseManifest,只要在这个任务之后改回来就好了,光这样也不行,因为不一定每个命令都会执行这个任务,所以改也要在assembleRelease系列任务里改,这里由于水平有限不知道哪个任务最合适,就选了一个processReleaseManifest执行之前的任务mergeReleaseResources,具体代码如下:

    void apply(Project project) {
        project.afterEvaluate {
            File manifest = new File("app/src/main/AndroidManifest.xml")
            String mText = manifest.text
            project.android.applicationVariants.all { variant ->
                //获取任务:因为不同build方式,方法名也不同,所以利用variant获取(参考virtualAPK)
                MergeResources mergeTask = project.tasks["merge${variant.name.capitalize()}Resources"]
                //doLast会在任务之后执行
                mergeTask.doLast {
                    String replaceText = mText.replaceAll("channelValue", project.channel)
                    manifest.write(replaceText)
                    println "mergeTask"
                }
                
                
                MergeManifests manifestTask = project.tasks["process${variant.name.capitalize()}Manifest"]
                manifestTask.doLast {
                    manifest.write(mText)
                    println "manifestTask"
                }
            }
        }
    }

好的,以上就可以完美运行了,gradle水太深....

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,663评论 25 708
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,974评论 6 342
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,010评论 19 139
  • 转载注明出处:http://www.jianshu.com/p/5255b100930e 0. 前言 完全由个人翻...
    王三的猫阿德阅读 2,581评论 0 4
  • 有些爱深藏在心底,默默地,深深地,也是一份美好的念想。 1 “老师,我男神这次又拿了五千元的奖学金,还是全校十佳大...
    王月英阅读 480评论 0 7