【问题标题】:How to change app name per Gradle build type如何更改每个 Gradle 构建类型的应用程序名称
【发布时间】:2014-09-07 05:54:45
【问题描述】:

我正在尝试找出一种方法,能够在 gradle 中更改每个构建类型的应用程序的应用程序名称。

例如,我希望调试版本具有 <APP_NAME>-debug,而 qa 版本具有 <APP-NAME>-QA

我熟悉:

debug {
        applicationIdSuffix '.debug'
        versionNameSuffix '-DEBUG'
}

但是,在启动器中,我似乎找不到 gradle 命令来应用应用程序的更改。

【问题讨论】:

    标签: android android-gradle-plugin


    【解决方案1】:

    如果“应用程序名称”是指android:label 上的<application>,最简单的解决方案是将该点指向一个字符串资源(例如,android:label="@string/app_name"),然后在其中拥有该字符串资源的不​​同版本src/debug/ 源集。

    您可以在this sample project 中看到,我在src/debug/res/values/strings.xml 中替换了app_name,它将应用于debug 构建。 release 构建将使用src/main/ 中的app_name 版本。

    【讨论】:

    • 这个解决方案不是意味着我们必须为每个翻译添加一个额外的 strings.xml 吗?这可能会成为一种痛苦的维护......
    • @sfera:首先,如果您愿意,欢迎您将此字符串隔离在其自己的资源文件中。其次,这仅适用于一个字符串。第三,这仅适用于您要替换该字符串的构建类型。第四,除非您有一个没有共同语言的开发团队,否则您不需要翻译非release 字符串。
    • 隔离字符串听起来是个好主意。感谢那!至于非release 部分,我认为这有点不同,因为人们可能还想测试本地化问题,同时允许“发布”和“测试”构建在同一设备上共存。在这种情况下,两个版本可能最终都带有相同的启动器标签,可能会引起一些混乱。这就是我试图避免的。
    • @sfera:“这就是我试图避免的”——所以,不要翻译这个字符串。无论如何,对该字符串的测试都是无效的,因为根据定义,它不是您要在release 模式下使用的字符串。并且仅将此字符串资源用于app_name,而不用于任何其他角色。
    • @sfera:你永远不会发布带有“AppNom-DEBUG”的应用程序。您可以使用“AppNom”发布应用程序。因此,测试“AppNom-DEBUG”是不必要的。当然欢迎您翻译app_name 的调试版本,即使这不是必需的(例如,您有不会说英语的法语或德语开发人员,因此需要翻译它)。为了测试未修改的release 版本的app_name 是否有效,以及它的翻译,测试release 构建,或创建一个near-release 构建类型,只添加应用程序ID 后缀并保留字符串。
    【解决方案2】:

    应用名称是用户可见的,这就是 Google 鼓励您将其保留在您的 strings.xml 文件中的原因。您可以定义一个单独的字符串资源文件,其中包含特定于您的 buildTypes 的字符串。听起来您可能有一个自定义的qa buildType。如果不是这样,请忽略下面的 qa 部分。

    └── src
        ├── debug
        │   └── res
        │       └── buildtype_strings.xml
        ├── release
        │   └── res
        │       └── buildtype_strings.xml
        └── qa
            └── res
                └── buildtype_strings.xml
    

    【讨论】:

    【解决方案3】:

    对于更动态的基于 gradle 的解决方案(例如,在 main 的 strings.xml 中设置一个基本应用程序名称一次,并避免在每个风味/构建类型组合的 strings.xml 中重复自己),请在此处查看我的答案:https://stackoverflow.com/a/32220436/1128600

    【讨论】:

      【解决方案4】:

      你可以使用这样的东西

       buildTypes {
          debug {
              applicationIdSuffix '.debug'
              versionNameSuffix '-DEBUG'
              resValue "string", "app_name", "AppName debug"
          }
          release {
              minifyEnabled true
              shrinkResources true
              proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
              signingConfig signingConfigs.release
              zipAlignEnabled true
              resValue "string", "app_name", "AppName"
          }
      }
      

      您可以在 AndroidManifest.xml 文件中使用 @string/app_name

      确保从 values/ 文件夹中删除 app_name(没有使用此名称的条目)。

      【讨论】:

      • 非常适合必须从外部文件中读取应用程序名称
      • 以这种方式构建时出错。任务“:app:mergeDebugResources”执行失败。资源重复:res/values/strings.xml:string/app_name
      • 如果你得到: 以这种方式构建时出错。任务':app:mergeDebugResources'的执行失败..重复资源:res/values/strings.xml:string/app_name 你应该这样做,就像它写的那样:“确保你从值/文件夹中删除app_name(没有这个名字的条目)。”
      • 我喜欢这个,因为字符串文件夹解决方案(上面接受的解决方案)仅在为特定源集/产品风格定义了应用程序名称时才有效。就我而言,我正在设置一个 Jenkins Pipeline 作业,以使用不同的名称自动构建我们应用程序的不同版本,并且并非所有这些名称都为它们定义了 productFlavors。所以 Jenkins 只是简单地通过环境提供应用名称,然后 gradle 读取它:resValue "string", "app_name", System.getenv("APP_NAME") ?: "MyApp"
      • 如果我从字符串文件夹中删除了 app_name,然后得到错误编译时间得到错误 -Error:Execution failed for task ':app:processDevDebugManifest'。 > 清单合并失败并出现多个错误,请参阅日志
      【解决方案5】:

      你可以用 gradle 做到这一点:

      android {
          buildTypes {
              release {
                  manifestPlaceholders = [appName: "My Standard App Name"]
              }
              debug {
                  manifestPlaceholders = [appName: "Debug"]
              }
          }
      }
      

      然后在你的AndroidManifest.xml 中输入:

      <application
          android:label="${appName}"/>
          <activity
              android:label="${appName}">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
      
                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
      </application>
      

      注意:它也适用于productFlavors

      【讨论】:

      • 出现错误 - 错误:任务 ':app:processDevDebugManifest' 的执行失败。 > 清单合并失败并出现多个错误,请参阅日志
      • 不工作---buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { manifestPlaceholders = [appName: "GridL Debug" ] applicationIdSuffix ".dev1" } }
      • 这是唯一对我有用的方法,更糟糕的是游戏控制台上的错误报告。它说我的图标是错误的,但实际上它是我的应用程序名称!这有帮助!谢谢大佬!!
      【解决方案6】:

      为了支持翻译,请这样做:

      1.删除字符串“app_name”

      2.添加到gradle

       buildTypes {
          admin {
             resValue "string", "app_name", "@string/app_name_admin"
          }
          release {
              resValue "string", "app_name", "@string/app_name_release"
          }
          debug {
              resValue "string", "app_name", "@string/app_name_debug"
          }
      }
      

      3. 将 Manifest 中的应用名称设置为“@string/app_name”

      4.添加到strings.xml值

      <string name="app_name_admin">App Admin</string>
      <string name="app_name_release">App  release</string>
      <string name="app_name_debug">App debug</string>
      

      【讨论】:

      • 有哪些不同的构建类型?除了 admin、release 和 debug 吗?
      • @DineshVG 你可以自己设置差异,例如不同的applicationId
      • 我想在另一个构建配置中使用 UIAutomator 测试,而不是使用不同的 pro-guard 规则进行调试。这可能吗?
      • 这应该是公认的答案,对我很有用
      • 我非常喜欢这种方法,因为它甚至允许您在 build.gradle 文件的 productFlavors 部分添加自定义 app_name。一种在您需要时非常方便和灵活的方法。
      【解决方案7】:

      我们需要一个解决方案来支持本地化的应用名称(适用于多语言)。 我已经使用@Nick Unuchek 解决方案进行了测试,但是构建失败(未找到@string/)。稍作改动即可修复此错误: build.gradle 文件:

      android {
          ext{
              APP_NAME = "@string/app_name_default"
              APP_NAME_DEV = "@string/app_name_dev"
          }
      
          productFlavors{
      
              prod{
                  manifestPlaceholders = [ applicationLabel: APP_NAME]
              }
      
              dev{
                  manifestPlaceholders = [ applicationLabel: APP_NAME_DEV ]
              }
      
          }
      

      值\strings.xml:

      <resources>
          <string name="app_name_default">AAA prod</string>
          <string name="app_name_dev">AAA dev</string>
      
      </resources>
      

      值-en\strings.xml:

      <resources>
          <string name="app_name_default">AAA prod en</string>
          <string name="app_name_dev">AAA dev en</string>
      
      </resources>
      

      Manifest.xml:

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

      【讨论】:

      • 像“极品飞车”这样的游戏在德国永远不会被称为“Bedürfnis nach Geschwindigkeit”。除非它是从一个可疑的开发者那里抄袭的......
      • 它工作。太感谢了。但是,就我而言,我需要在 application 中添加 1 个 tools:replace="android:label" AndroidManifest
      【解决方案8】:

      您可以在不同的文件夹中使用strings.xml,参见Android separate string values for release and debug builds

      所以,创建这个文件:

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <string name="app_name">Your app name</string>
      </resources>
      

      然后将其粘贴到app\src\debug\res\values\app\src\release\res\values\ 文件夹。在调试和发布文件中替换“您的应用名称”。从app\src\main\res\values\ 文件夹中的strings.xml 中删除app_name 项目。

      AndroidManifest 你将拥有相同的

      <application
          android:label="@string/app_name"
          ...
      

      完全没有变化。即使您添加了带有 AndroidManifest 文件和 strings.xml 的库。

      【讨论】:

        【解决方案9】:

        由于作者要求在 Gradle 中执行此操作,我们可以假设他希望在脚本中而不是在配置文件中执行此操作。由于 Android StudioGradle 在去年(~2018 年)都进行了大量更新和修改,因此上述所有其他答案似乎都过于曲解了。最简单的方法是将以下内容添加到您的app/build.gradle

        android {
            ...
            buildTypes {
                ...
                // Rename/Set default APK name prefix (app*.apk --> AwesomeApp*.apk)
                android.applicationVariants.all { variant ->
                    variant.outputs.all { output ->
                        def appName = "AwesomeApp"
                        outputFileName = appName+"-${output.baseName}-${variant.versionName}.apk"
                }
            }
        }
        

        【讨论】:

          【解决方案10】:

          您可以采取多种方式。

          您可以在应用级别build.gradle 中创建manifestPlaceholders resValue。例如

          buildTypes {
               release {
                    ...
                    manifestPlaceholders = [appLabel: "My App"]
                    //resValue "string", "appLabel", '"My App"'
               }
               debug {
                    ...
                    manifestPlaceholders = [appLabel: "My App - Debug"]
                    //resValue "string", "appLabel", '"My App - Debug"'
               }
          }
          

          如果你有productFlavors,你可以在那里创建

          flavorDimensions "env"
          productFlavors {
              dev {
                  dimension "env"
                  ...
                  manifestPlaceholders = [appLabel: "My App - Development"]
                  //resValue "string", "appLabel", '"My App - Development"'
              }
              prod {
                  dimension "env"
                  ...
                  manifestPlaceholders = [appLabel: "My Awesome App"]
                  //resValue "string", "appLabel", '"My Awesome App"'
              }
          }
          

          然后在AndroidManifest.xml中,如果您使用manifestPlaceholders,只需将android:label="${appLabel}"更改为如下如果您使用resValue,只需更改android:label=@string/appLabel

          <application
              ...
              android:label="${appLabel}"> //OR `android:label=@string/appLabel`
              
              <activity
                  ...
                  android:label="${appLable}">
          
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
          
                      <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
              </activity>
          </application>
          

          注意:确保在LAUNCHER 类别中的&lt;activity&gt; 中也更改android:lable。如果不需要在&lt;activity&gt; 中使用android:label,只需删除它即可。


          如果不想直接添加build.gradle,可以添加选中ProductFlavorsvalues/string.xml。例如

          添加

          <string name="appLabel">My App - Development</string> 
          

          app/src/dev/res/values/string.xml

          <string name="appLabel">My Awesome App</string> 
          

          app/src/prod/res/values/string.xml

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-05-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-31
            • 1970-01-01
            相关资源
            最近更新 更多