仅限Gradle的解决方案,用于根据Build Variant修改App名称

时间:2016-06-12 10:00:53

标签: android android-productflavors android-build-type manifest-merging

我正在尝试修改我的gradle文件,以便根据FlavorBuild Type为我的应用添加不同的名称。到目前为止,我已成功通过Android Gradle Plugin Docs

使用Flavor技术基于Manifest Merging进行命名。

电流

这些是我的主屏幕上debugrelease版本的应用程序名称。

Flavor     Debug App Name             Release App Name
--------   --------------             ----------------
entity_1   App Name                   App Name
entity_2   App Name                   App Name
...        ...                        ...
entity_2   App Name                   App Name
hub        Hub                        Hub

它很接近,但是......

所需

Flavor     Debug App Name             Release App Name
--------   --------------             ----------------
entity_1   App Name - Entity_1_name   App Name
entity_2   App Name - Entity_2_name   App Name
...        ...                        ...
entity_n   App Name - Entity_n_name   App Name
hub        Hub                        Hub

我想要这个,所以我知道哪个debug味道在我的主屏幕上。我并不关心区分release口味,因为用户在他们的设备上只有一个(可能有多个,但我不关心)

鉴于Gradle是如何可扩展的,我认为这是可能的;但是,我不是高级Gradle用户。

那么,我如何简洁(尽可能)扩展我的代码以获得我想要的输出?

注意:上表使用versionNameSuffix作为我的应用名称的后缀;但是,它可以是任何(另一个添加的变量??),这将允许我告诉我仅在我的调试构建类型中使用哪种风格。

非目标

代码

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "..."
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        manifestPlaceholders = [ applicationLabel:"App Name"]
    }

    productFlavors {
        entity_1 {
            versionNameSuffix ' - Entity_1_name'
            applicationIdSuffix 'entity_1'
        }
        entity_2 {
            versionNameSuffix ' - Entity_2_name'
            applicationIdSuffix 'entity_2'
        }
        hub {
            versionNameSuffix ' - Hub'
            applicationIdSuffix 'hub'
            manifestPlaceholders = [ applicationLabel:"Hub" ]
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

清单

<manifest ...>

    <application
        ...
        android:label="${applicationLabel}"
        ... >

更新

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    ext {
        APP_NAME = "App Name"
        HUB_NAME = "Hub"
    }

    defaultConfig {
        applicationId "..."
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    productFlavors {
        one_million {
            versionNameSuffix ' - Entity_1'
            applicationIdSuffix 'entity_1'
            manifestPlaceholders = [ applicationLabel: APP_NAME + versionNameSuffix ]
        }
        udacity {
            versionNameSuffix ' - Entity_2'
            applicationIdSuffix 'entity_2'
            manifestPlaceholders = [ applicationLabel: APP_NAME + versionNameSuffix ]
        }
        hub {
            versionNameSuffix ' - Hub'
            applicationIdSuffix 'hub'
            manifestPlaceholders = [ applicationLabel: HUB_NAME ]
        }
    }

    buildTypes {
        release {
            manifestPlaceholders = [ applicationLabel: APP_NAME ]
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

新输出

Flavor     Debug App Name             Release App Name
--------   --------------             ----------------
entity_1   App Name - Entity_1_name   App Name
entity_2   App Name - Entity_2_name   App Name
...        ...                        ...
entity_n   App Name - Entity_n_name   App Name
hub        Hub                        App Name          <- Issue (Release)

2 个答案:

答案 0 :(得分:5)

第一次尝试是对正确答案的更接近解决方案,而不是更新的代码。

可以通过移动manifestPlaceholders部分内的所有applicationVariants.all代码来进行进一步的重构;然而,这是半清洁,仅限摇篮的解决方案的工作副本......

android {
    ext {
        APP_NAME = "App Name"
        HUB_NAME = "Hub"
    }
    defaultConfig {
        manifestPlaceholders = [ applicationLabel: APP_NAME ]
    }
    productFlavors {
        entity_1 {
            versionNameSuffix ' - Entity_1'
            applicationIdSuffix 'entity_1'
        }

        ...

        entity_n {
            versionNameSuffix ' - Entity_n'
            applicationIdSuffix 'entity_n'
        }

        hub {
            versionNameSuffix ' - Hub'
            applicationIdSuffix 'hub'
            manifestPlaceholders = [ applicationLabel: HUB_NAME ]
        }
    }

    applicationVariants.all { variant ->
        // Don't modify the release build or the hub flavor. They are good already.
        if (variant.buildType.name == "release" || variant.flavorName == "hub") return
        variant.mergedFlavor.manifestPlaceholders = [applicationLabel: APP_NAME + variant.mergedFlavor.versionNameSuffix]
    }

注意:

BEFORE applicationVariants.all { ... }代码运行后,这就是所有applicationLabel的样子。我们很接近,但需要加入他们......

Flavor     Debug App Name             Release App Name
--------   --------------             ----------------
entity_1   App Name                   App Name
entity_2   App Name                   App Name
...        ...                        ...
entity_n   App Name                   App Name
hub        Hub                        Hub

AFTER applicationVariants.all { ... }代码运行后,这就是所有applicationLabel的样子。我们完成了!

Flavor     Debug App Name             Release App Name
--------   --------------             ----------------
entity_1   App Name - Entity_1_name   App Name
entity_2   App Name - Entity_2_name   App Name
...        ...                        ...
entity_n   App Name - Entity_n_name   App Name
hub        Hub                        Hub

同时 ...

defaultConfig无法访问个人productFlavors中的信息。虽然defaultConfigFlavor类型,但只有指定的Flavors可以从defaultConfig中读取信息。没有其他机制(我知道)。因此,您需要在defaultConfig

中设置最通用的类​​型

buildTypes块中的任何信息都将获得最终结果,applicationVariants.all中的代码不会覆盖该信息。为了克服这个问题,您必须从buildType块中删除所需的代码并将其移动到applicationVariants.all块中(使用正确的逻辑语句)

答案 1 :(得分:4)

克里斯托弗的解决方案并不适合我。我花了几个小时尝试不同的模式,我终于找到了一个适合我的情况,所以我会在这里分享。

首先,build.gradle中的productFlavors定义:

productFlavors {

    uat {
        manifestPlaceholders.appNameSuffix = " UAT"
    }

    live {
        manifestPlaceholders.appNameSuffix = ""
    }
}

然后,buildTypes:

buildTypes {

    debug {
        manifestPlaceholders.appName = "Preg Debug"
    }

    qa {
        manifestPlaceholders.appName = "Preg QA"
    }

    release {
        manifestPlaceholders.appName = "Pregnancy"
    }

}

最后但并非最不重要的是,清单中的android:label&gt;应用程序:

    android:label="${appName}${appNameSuffix}"

因此,我获得了应用名称的以下6种变体:

  • 妊娠
  • 怀孕UAT
  • Preg QA
  • Preg QA UAT
  • Preg Debug
  • Preg Debug UAT

因此,结论是,我必须在清单文件中连接来自产品风格和构建类型的清单占位符,等等!

在清洁,可读和可维护方面,我认为这是要走的路:)