我已经在Android Studio中实现了Flavors,现在我尝试将每个Flavor放在它自己的目录中,并使用自己独特的名称 - 遗憾的是,在某些情况下,名称与名称不同。 :(
我们的工具取决于它是否相同,所以如果我可以在gradle中将其拉出来,那就更好了。
我有一个使用版本名称后缀值作为目录名称并且有效的示例。但我想要做的是在flavor配置中的某个地方指定一个值,但是我发现当你设置一个具有相同名称的属性时,最后一个获胜 - 而不是按照配置中的指定使用每个属性。
所以,举个例子,假设我有两个口味:Jimbo和Randolph。但是我想把Jimbo.apk放在" jimmy"文件夹和Randolph.apk在" randy"夹。如何为每个将被选中并用于存储生成的APK的值(目录)指定?为了增加复杂性,我正在applicationVariants.all
重命名APK当前。
在下面的代码中,我希望以某种方式用我能以某种方式指定的变量替换versionNameSuffix
。
这就是我所拥有的:
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.mycompany.default"
minSdkVersion 14
targetSdkVersion 23
versionCode 11
versionName "1.0.11"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors {
Randolph {
applicationId 'com.mycompany.randy'
versionNameSuffix 'randy'
}
Jimbo {
applicationId 'com.mycompany.jimmy'
versionNameSuffix 'jimmy'
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def path = "C:/AndroidBuilds/MyCompany.Build/" + variant.productFlavors[0].versionNameSuffix + "/"
logger.error("Path = " + path)
def SEP = "-"
def flavor = variant.productFlavors[0].name
def version = variant.versionCode
def newApkName = path + version + SEP + flavor
logger.error("newApkName = " + newApkName)
output.outputFile = new File(newApkName + ".apk")
}
}
}
dependencies {
}
}
更新
根据使用任务的问题,我尝试了这种方法,但设置目录的问题仍然存在 - 使用属性(archivesBaseName
)使用最后一个集,因此所有文件都被复制到该目录。这是一个例子。由于我有超过100种口味要创建,我希望每个都发送到它自己的目录和配置驱动。这是我试过的:
productFlavors {
Randolph {
applicationId 'com.mycompany.randy'
setProperty("archivesBaseName", "randy")
}
Jimbo {
applicationId 'com.mycompany.jimmy'
setProperty("archivesBaseName", "jimmy")
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def path = "C:/AndroidBuilds/MyCompany.Build/" + archivesBaseName + "/"
logger.error("Path = " + path)
def SEP = "-"
def flavor = variant.productFlavors[0].name
def version = variant.versionCode
def newApkName = path + version + SEP + flavor
logger.error("newApkName = " + newApkName)
output.outputFile = new File(newApkName + ".apk")
def copyApkTask = tasks.create(name: "copy" + variant.name + "Apk") {
copy {
def newName = newApkName + ".apk"
logger.error("from = " + newName)
logger.error("into = " + path)
logger.error("old name = " + version + SEP + flavor + ".apk")
logger.error("new name = " + flavor + ".apk")
from newName
into path
rename (version + SEP + flavor + ".apk", flavor + ".apk")
}
}
copyApkTask.mustRunAfter variant.assemble
}
}
在上面的示例中,我添加了一项任务,以便将具有不同名称的APK另外复制到特定于风味的目录。所有的APK最终都被复制到最后指定的`archivesBaseName,即" jimmy"。所以最后一个赢了。我希望它会像一个变量。我宁愿不要有100多个if语句来执行此操作,并且更愿意在Gradle中执行此操作。我开始怀疑是否需要进行外部Ant调用以使这一切都能正常工作。
答案 0 :(得分:1)
问题是setProperty正在设置Project属性,因此它总是被覆盖。一个简单的解决方案是使用Varients Extra Property。这样的事情。
productFlavors {
Randolph {
applicationId 'com.mycompany.randy'
ext.archivesBaseName = "randy" }
Jimbo {
applicationId 'com.mycompany.jimmy'
ext.archivesBaseName=jimmy" }
}
然后您将在任务中访问它
def path = "C:/AndroidBuilds/MyCompany.Build/" + variant.ext.archivesBaseName + "/"
我还没有测试过它,它可能有一个错误,需要一些调整。
<强>更新强>
这还不够,因为Gradle将设置为flavor对象的ext属性,只有在flavor对象中定义它。否则,它将在父对象或根对象中设置它,即项目。因此,为了使其工作,我们首先必须在flavor对象中定义属性。这可以在@Stephen在下面回答时完成。按照他的测试方法。
还有3个选项:
1.通过预先挂起样式名称,为每个样式使用不同的变量名称,例如&#34; Jimbo_archivesBaseName&#34;。然后使用property(flavorName +&#34; _archivesBaseName)访问它;
2.使用全局HashMap变量,为每个flavor名称设置路径
3.使用一个函数,它返回一个基于flavor名称的路径。
答案 1 :(得分:1)
好的,最后这个特定的链接真的帮助了我需要的变量赋值:
Android Studio: Gradle Product Flavors: Define custom properties
基本上你可以在风味中分配变量。这是我最终做的事情,实际上比我开始时更进一步,因为现在我可以使用Flavor作为APK名称或指定一个(我知道,它搞砸了,但历史可以这样!) :
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId "com.mycompany.default"
minSdkVersion 14
targetSdkVersion 23
versionCode 11
versionName "1.0.11"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
signingConfig signingConfigs.config
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
productFlavors.whenObjectAdded { flavor ->
// Add the property 'myCustomProperty' to each product flavor and set the default value to 'customPropertyValue'
flavor.ext.set('directoryPath', '')
flavor.ext.set('apkName', '')
}
productFlavors {
Randolph {
applicationId 'com.mycompany.randy'
directoryPath = 'randy'
apkName = 'RandyBoy' // If you want the APK name be different than the flavor
}
Jimbo {
applicationId 'com.mycompany.jimmy'
directoryPath = 'jimmy'
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def path = "C:/AndroidBuilds/MyCompany.Build/" + variant.productFlavors[0].directoryPath + "/"
def SEP = "-"
def apkName = variant.productFlavors[0].apkName
def flavor = variant.productFlavors[0].name
if (apkName != '')
flavor = apkName;
def version = variant.versionCode
def newApkName = path + version + SEP + flavor
logger.error("newApkName = " + newApkName)
output.outputFile = new File(newApkName + ".apk")
}
}
}
dependencies {
}
}
因此productFlavors.whenObjectAdded
设置每种风味的默认值,然后由每种风味覆盖。在applicationVariants.all
中,检查是否已覆盖apkName
,如果是,则使用它,否则它使用flavor名称(并且版本代码在其前面添加)。该目录由味道直接设置。
非常感谢@lionscribe。他让我更清楚地思考这个问题。