应党中央(主席)要求,用代码实现动态指定一个渠道号
首先第一步自定义一个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水太深....