5

我正在尝试修改我的 gradle 文件以允许我的应用程序基于Flavor和使用不同的名称Build 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/GradleString Resource的答案中的解决方案不感兴趣: App name based on build type *and* product flavor 。首选纯基于 Gradle 的解决方案。

  • Manifest Merger对放弃我目前实施的方法不感兴趣。https://stackoverflow.com/a/28465883/2333021的答案是实现我已经完成的工作的另一种方式,并且不允许我只在调试版本上执行此操作(我可以看到。如果确实如此,然后让我知道)。

代码

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)
4

2 回答 2

5

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

进一步的重构可以通过将所有manifestPlaceholders代码移动到该applicationVariants.all部分中来完成;然而,这是一个半干净的、仅限 gradle 的解决方案的工作副本......

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]
    }

笔记:

在代码运行之前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

代码运行后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块中(使用正确的逻辑语句)

于 2016-06-12T13:12:27.650 回答
5

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

一、build.gradle中productFlavors定义:

productFlavors {

    uat {
        manifestPlaceholders.appNameSuffix = " UAT"
    }

    live {
        manifestPlaceholders.appNameSuffix = ""
    }
}

然后,构建类型:

buildTypes {

    debug {
        manifestPlaceholders.appName = "Preg Debug"
    }

    qa {
        manifestPlaceholders.appName = "Preg QA"
    }

    release {
        manifestPlaceholders.appName = "Pregnancy"
    }

}

最后但同样重要的是,清单 > 应用程序中的 android:label:

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

结果,我得到了以下 6 个应用名称变体:

  • 怀孕
  • 怀孕 UAT
  • 预质量保证
  • Preg QA UAT
  • 预调试
  • Preg 调试 UAT

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

就清洁、可读和可维护而言,我认为这是要走的路:)

于 2017-07-13T09:17:04.350 回答