Android Studio自定义模板升级后build.gradle合并问题求助
我之前也遇到过类似的情况,AS 3.0到3.1的版本迭代中,模板系统对Gradle文件的合并逻辑做了不少细节调整——哪怕<merge>标签写法和其他模板一致,也可能因为模板内容或变量兼容问题导致失败。结合你的情况,给你几个针对性的解决方案:
1. 检查FTL模板变量与AS 3.1+的兼容性
AS 3.1+对模板上下文的变量传递做了更严格的校验,比如你在build.gradle.ftl中用到的${gradlePluginVersion}变量,要确保你的recipe.xml.ftl已经正确传递了这个值,或者和AS默认模板的变量名保持一致。
比如可以在<merge>标签前添加变量声明:
<set property="gradlePluginVersion" value="3.1.1" />
如果是继承AS的默认模板,也要确认变量名没有变更——AS 3.1+中根Gradle插件版本的变量依然是gradlePluginVersion,但个别场景下可能会用pluginVersion,可以对比默认模板的变量名调整。
2. 替换<merge>标签为<instantiate>或<copy>
AS 3.1+对<merge>标签的冲突处理逻辑更严格,尤其是根build.gradle这种AS会自动生成默认内容的文件,合并时很容易因为内容重叠(比如buildscript块、allprojects块)导致失败。
尝试直接生成完整的build.gradle文件,替换原来的<merge>为:
<instantiate from="root/build.gradle.ftl" to="${escapeXmlAttribute(projectOut)}/build.gradle" />
如果需要保留AS默认生成的部分内容,可以先备份再合并:
<copy from="${escapeXmlAttribute(projectOut)}/build.gradle" to="${escapeXmlAttribute(projectOut)}/build.gradle.backup" /> <merge from="root/build.gradle.ftl" to="${escapeXmlAttribute(projectOut)}/build.gradle" />
3. 对齐AS 3.1+默认build.gradle的结构
对比AS 3.1+新建项目自动生成的根build.gradle,调整你的FTL模板结构,确保两者的块顺序、语法完全一致。比如AS 3.1+默认会把google()仓库放在jcenter()前面,且会包含kotlin版本声明(如果启用Kotlin),如果你的模板结构和默认结构差异过大,合并时就会出错。
举个AS 3.1+默认根build.gradle的参考结构:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.2.30' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir }
把你的FTL模板调整成这个结构,合并时冲突概率会大幅降低。
4. 开启模板调试模式定位具体错误
如果上述方法都没解决,建议开启AS的模板调试日志,找到具体的失败原因:
- 打开AS的
Help -> Edit Custom VM Options,添加一行:-Dandroid.template.log.level=debug - 重启AS,尝试创建新项目,然后查看AS的日志目录(Windows在
C:\Users\<你的用户名>\.AndroidStudio3.1\system\log,Mac在~/Library/Logs/AndroidStudio3.1),里面会有模板生成的详细日志,能看到合并时是变量缺失、语法错误还是内容冲突。
内容的提问来源于stack exchange,提问作者masztalski

