我的项目有两种:
flavor1 -> packagename: com.example.flavor1
flavor2 -> packagename: com.example.flavor2
现在我想构建一个flavor1和flavor2的构建变量。 buildvariant的唯一区别是另一个packagename。
我的项目使用MapFragments并且只有一个Manifest - 所以我将MAPS_RECEIVE的权限名称放在我各自风格的字符串资源文件中。
问题是:如何替换buildvariant的字符串资源?
我尝试了以下方法(described in this post):
buildTypes{
flavor1Rev{
packageName 'com.example.rev.flavor1'
filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: ['package_permission' : 'com.example.rev.flavor1.permission.MAPS_RECEIVE'])
}
}
但是使用这个我得到了这个错误:
找不到参数的方法filter() [{令牌= {package_permission = com.example.rev.flavor1.permission.MAPS_RECEIVE}}, BuildTypeDsl_D ecorated {name = ReplaceTokens,debuggable = false, jniDebugBuild = false,renderscript DebugBuild = false, renderscriptOptimLevel = 3,packageNameSuffix = null,versionNameS uffix = null,runProguard = false,zipAlign = true,signingConfig = null}] on BuildTypeD sl_Decorated {name = buderusFinal,debuggable = false, jniDebugBuild = false,renderscr iptDebugBuild = false, renderscriptOptimLevel = 3,packageNameSuffix = null,versionNa meSuffix = null,runProguard = false,zipAlign = true,signingConfig = null}。
我是否必须为过滤方法定义自己的任务?
编辑[2013_07_09]:
src / flavor1 / res中的字符串:
<string name="package_permission">package_permission</string>
build.gradle中的代码替换字符串:
buildTypes{
flavor1Rev{
copy{
from('src/res/'){
include '**/*.xml'
filter{String line -> line.replaceAll(package_permission, 'com.example.rev.flavor1.permission.MAPS_RECEIVE')}
}
into '$buildDir/res'
}
}
}
答案 0 :(得分:37)
我自己解决了这个问题,所以这里的解决方案是“一步一步” - 也许它会帮助其他一些新手学习:)
一般复制任务:
copy{
from("pathToMyFolder"){
include "my.file"
}
// you have to use a new path for youre modified file
into("pathToFolderWhereToCopyMyNewFile")
}
替换General中的一行:
copy {
...
filter{
String line -> line.replaceAll("<complete line of regular expression>",
"<complete line of modified expression>")
}
}
我认为最大的问题是获得正确的路径,因为我必须动态地(this link was very helpful for me)。我通过替换清单中的特殊行而不是字符串文件来解决我的问题。
以下示例显示如何替换清单中的“元数据”标签以使用google-maps-api-key(在我的情况下,有不同的口味使用不同的密钥):
android.applicationVariants.each{ variant ->
variant.processManifest.doLast{
copy{
from("${buildDir}/manifests"){
include "${variant.dirName}/AndroidManifest.xml"
}
into("${buildDir}/manifests/$variant.name")
// define a variable for your key:
def gmaps_key = "<your-key>"
filter{
String line -> line.replaceAll("<meta-data android:name=\"com.google.android.maps.v2.API_KEY\" android:value=\"\"/>",
"<meta-data android:name=\"com.google.android.maps.v2.API_KEY\" android:value=\"" + gmaps_key + "\"/>")
}
// set the path to the modified Manifest:
variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml")
}
}
}
答案 1 :(得分:11)
我几乎完全使用你想要的方法。 replaceInManfest
也是通用的,也可以用于其他占位符。 getGMapsKey()
方法只返回基于buildType的相应键。
applicationVariants.all { variant ->
def flavor = variant.productFlavors.get(0)
def buildType = variant.buildType
variant.processManifest.doLast {
replaceInManifest(variant,
'GMAPS_KEY',
getGMapsKey(buildType))
}
}
def replaceInManifest(variant, fromString, toString) {
def flavor = variant.productFlavors.get(0)
def buildtype = variant.buildType
def manifestFile = "$buildDir/manifests/${flavor.name}/${buildtype.name}/AndroidManifest.xml"
def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll(fromString, toString)
new File(manifestFile).write(updatedContent, 'UTF-8')
}
如果你想看看它是否会在以后发展,我也会在gist
上完成它。
我发现这是一种比其他方法更优雅和更通用的方法(尽管令牌替代只是工作会更好)。
答案 2 :(得分:2)
答案已经过时了,现在有更好的方法可以归档它。您可以在build.gradle中使用该命令:
tasklist /v /fi "WINDOWTITLE eq test.bat - Notepad" | findstr /C:"No tasks are running"
if %errorlevel% NEQ 0 (
echo awesome
) else (
echo Prog not running
)
并在你的清单中:
manifestPlaceholders = [
myPlaceholder: "placeholder",
]
可在此处找到更多信息: https://developer.android.com/studio/build/manifest-merge.html
答案 3 :(得分:0)
在当前的Android Gradle DSL中,ApplicationVariant
类已更改,并且必须重写Saad的方法,例如如下:
applicationVariants.all { variant ->
variant.outputs.each { output ->
output.processManifest.doLast {
replaceInManifest(output,
'GMAPS_KEY',
getGmapsKey(buildType))
}
}
}
def replaceInManifest(output, fromString, toString) {
def updatedContent = output.processManifest.manifestOutputFile.getText('UTF-8')
.replaceAll(fromString, toString)
output.processManifest.manifestOutputFile.write(updatedContent, 'UTF-8')
}
新的DSL还提供了一种更清晰的方法来直接获取清单文件。