【问题标题】:How to customize the APK file name for product flavors?如何自定义产品风味的 APK 文件名?
【发布时间】:2014-09-26 01:54:15
【问题描述】:

我正在 build.gradle 脚本中自定义我的 Android 应用程序的 APK 文件名,如下所示:

android {
    defaultConfig {
        project.ext.set("archivesBaseName", "MyApplication");
    }
}

现在我正在使用产品风味:

android {
    productFlavors {
        green {
            applicationId "com.example.myapplication.green"
        }

        blue {
            applicationId "com.example.myapplication.blue"
        }
    }
}

有没有办法自定义每个 APK 的名称?我尝试了archiveBaseNamebaseName,但没有成功。最后我想提出以下文件:

build/outputs/apk/Blue-debug-1.2.1.apk
build/outputs/apk/Blue-debug-unaligned.apk
build/outputs/apk/Blue-release-1.2.1.apk
build/outputs/apk/Blue-release-unaligned.apk
build/outputs/apk/Green-debug-1.2.1.apk
build/outputs/apk/Green-debug-unaligned.apk
build/outputs/apk/Green-release-1.2.1.apk
build/outputs/apk/Green-release-unaligned.apk

【问题讨论】:

    标签: android gradle android-gradle-plugin build.gradle android-productflavors


    【解决方案1】:

    这将在 2021 年帮助您。

    android {
        
    //........
    flavorDimensions "version"
    productFlavors {
        Free {
            dimension "version"
            applicationId "com.exampleFree.app"
        }
        Paid {
            dimension "version"
            applicationId "com.examplePaid.app"
        }
    }
    
    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            def appId = variant.applicationId// com.exampleFree.app OR com.examplePaid.app
            def versionName = variant.versionName
            def versionCode = variant.versionCode // e.g 1.0
            def flavorName = variant.flavorName // e. g. Free
            def buildType = variant.buildType.name // e. g. debug
            def variantName = variant.name // e. g. FreeDebug
    
            //customize your app name by using variables
            outputFileName = "${variantName}.apk"
        }
    }}
    

    Apk 名称 FreeDebug.apk

    证明

    【讨论】:

    • 不适合我,它什么也没做。我添加了一个“println outputFileName”,它打印正确,但由于某种原因,gradle 没有使用文件名的“outputFileName”值。顺便说一句,我正在尝试将它用于 app bundle,而不是 APK。
    • 在 2021 年使用 Bundles 时不起作用。
    • 与 APK 完美搭配。
    【解决方案2】:

    这里的每个答案都是一样的,而且已经过时了。很容易做到[风味]-[版本]-[构建类型]:

    android {
        productFlavors {
            green {
                applicationId "com.example.myapplication.green"
                setProperty("archivesBaseName", "Green-" + defaultConfig.versionName)
            }
    
            blue {
                applicationId "com.example.myapplication.blue"
                setProperty("archivesBaseName", "Blue-" + defaultConfig.versionName)
            }
        }
    }
    

    如果你的 versionName 是“1.2.1”,运行 gradle assemble 会产生:

    Green-1.2.1-debug.apk

    Green-1.2.1-release.apk

    Blue-1.2.1-debug-apk

    Blue-1.2.1-release.apk

    【讨论】:

      【解决方案3】:

      这是你需要的

      android {
          defaultConfig {
              ……
      
              // custom output apk name
              applicationVariants.all { variant ->
                  variant.outputs.all {
                      outputFileName = "${variant.productFlavors[0].name}-${variant.buildType.name}-${variant.versionName}.apk"
                  }
              }
          }
          ……
      }
      

      【讨论】:

        【解决方案4】:

        对于 Android Studio 3.0,您必须更改:

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                output.outputFile = new File(output.outputFile.parent, "whatever" + ".apk")
            }
        }
        

        收件人:

        android.applicationVariants.all { variant ->
                variant.outputs.all { 
                    outputFileName = "whatever" + ".apk")
            }
        }
        

        【讨论】:

          【解决方案5】:

          试着把它放在你的 build.gradle 的 android 闭包中

          buildTypes {
              debug {
                  // debug buildType specific stuff
              }
              release {
                  // release buildType specific stuff
              }
              applicationVariants.all { variant ->
                  if (variant.buildType.name.equals("release") &&
                      variant.productFlavors[0].name.equals("green") &&
                      variant.zipAlign) {
                          def apk = variant.outputFile;
                          variant.outputFile = new File(apk.parentFile, "green.apk");
                  } else if(variant.buildType.name.equals("release") &&
                      variant.productFlavors[0].name.equals("blue") &&
                      variant.zipAlign) {
                          def apk = variant.outputFile;
                          variant.outputFile = new File(apk.parentFile, "blue.apk");
                  }
              }
          }
          

          现在输出应该类似于green.apkblue.apk

          【讨论】:

          • 如果你对“freeflavor”和“proflavor”都做同样的事情,为什么还要检查产品风味名称?我真正想要的是像您的示例中那样更改“模块名称”-不附加任何内容。
          • 仍然:我之前问过你有两个 if 块的原因是什么?
          • 是的。它在这里没有多大用处,可以进一步简化。
          • if 语句圆括号不完整......虽然即使把它们放在那里对我也没有影响
          • 这不起作用,缺少paren并且显然与Android插件不兼容?我收到有关未定义属性 outputFile 的错误。请参阅下面的答案,其中显示了我是如何修复它的。
          【解决方案6】:

          这是我上面 Lakshman 答案的变体(呵呵),不知道为什么我需要“variants.outputs.each”,但我确实需要。

          defaultConfig {
              applicationId "my.company.com"
              minSdkVersion 16
              targetSdkVersion 25
              applicationVariants.all { variant ->
                  if (variant.productFlavors[0].name.equals("VariantA")) {
                      variant.outputs.each { output ->
                          def apk = output.outputFile;
                          output.outputFile = new File(apk.parentFile, "Blue.apk");
                      }
                  } else { // Only two variants
                      variant.outputs.each { output ->
                          def apk = output.outputFile;
                          output.outputFile = new File(apk.parentFile, "Green.apk");
                      }
                  }
              }
          }
          

          【讨论】:

            【解决方案7】:

            这对我有用:

            在 APK 名称中添加 variant.productFlavors[0].name

            代码示例:

            buildTypes {
                release {
                    minifyEnabled false
                    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                    applicationVariants.all { variant ->
                        variant.outputs.each { output ->
                            output.outputFile = new File(output.outputFile.parent, "APPNAME_" + variant.productFlavors[0].name + "_" + variant.versionName + ".apk")
            
                        }
                    }
                }
            }
            

            【讨论】:

              【解决方案8】:

              我正在使用以下内容,因此文件不会相互覆盖:

              applicationVariants.all { variant ->
                  variant.outputs.each { output ->
                      def newApkName = variant.name + "-" + variant.versionName + "(" + variant.versionCode +")" + ".apk";
                      output.outputFile = new File("${project.projectDir}/outputs/apk/" + variant.name, newApkName);
                  }
              }
              

              【讨论】:

                【解决方案9】:

                我是这样做的:

                productFlavors {
                        production {
                            applicationId "com.example.production"
                        }
                
                        staging {
                            applicationId "com.example.production.staging"
                
                        }
                
                        applicationVariants.all { variant ->
                            variant.outputs.each { output ->
                                if(variant.productFlavors[0].name.equals("staging")){
                                    output.outputFile = new File(output.outputFile.parent,
                                            output.outputFile.name.replace("app-staging-release",  "test"));
                
                                }else{
                                    output.outputFile = new File(output.outputFile.parent,
                                            output.outputFile.name.replace("app-production-release",  "production"));
                                }
                
                            }
                        }
                    }
                

                【讨论】:

                • 什么是outputFile??
                【解决方案10】:

                对于 Android Gradle 插件 0.13.+,您应该使用如下内容:

                android{
                    buildTypes {
                        applicationVariants.all { variant ->
                            variant.outputs.each { output ->
                                def apk = output.outputFile;
                                def newName = "mysms-" + variant.baseName.replace("-release", "") + "-" + defaultConfig.versionName + ".apk";
                                output.outputFile = new File(apk.parentFile, newName);
                            }
                        }
                    }
                }
                

                【讨论】:

                • 这已在 Android Gradle 3.0.0-alpha1 中停止工作。您似乎无法再访问 outputFile。
                • 如果你不想更新你的 gradle 版本真的很有用!
                【解决方案11】:

                Android Gradle Plugin 0.13.0 已弃用以下中使用的 outputFile:

                applicationVariants.all { variant ->
                    def newApkName = variant.name + "my-custom-addition" + ".apk";
                    variant.outputFile = new File("${project.buildDir}/outputs/apk/", newApkName);
                }
                

                对我有用的解决方案是:

                android {
                ... 
                }
                
                project.archivesBaseName = "AndroidAppGeneric-${_buildVersionNameForMaven}"
                

                【讨论】:

                  【解决方案12】:

                  你需要这个很奇怪,因为默认情况下,apk 文件名已经不同了。

                  如果您查看第 1346 行的 here,您可以看到在 outputFile 中使用了 variantData.variantConfiguration.baseName。

                  variantData.outputFile = project.file("$project.buildDir/apk/${project.archivesBaseName}-${variantData.variantConfiguration.baseName}.apk")
                  

                  baseName 的文档是

                  /**
                   * Full, unique name of the variant, including BuildType, flavors and test, dash separated.
                   * (similar to full name but with dashes)
                   */
                  private String mBaseName;
                  

                  所以运行gradle assembleFreeDebug 应该会得到一个ProjectName-free-debug.apk 文件。

                  但如果不是这样,或者你想要一个不同的文件名,你可以使用下面的代码来自定义它。

                  android {
                      buildTypes {
                          debug {}
                          alpha {}
                          release {}
                      }
                      productFlavors {
                          free{}
                          paid{}
                      }
                      applicationVariants.all { variant ->
                          def newApkName = variant.name + "my-custom-addition" + ".apk";
                          variant.outputFile = new File("${project.buildDir}/outputs/apk/", newApkName);
                      }
                  }
                  

                  【讨论】:

                  • 快到了。 (1) 出于某种原因,build/outputs/apk 中的 -unaligned.apk 文件仍带有 MyApplication 前缀。 (2) 变体不大写。
                  • 知道如何完成这个吗?
                  • (1) 根据 BasePlugin.groovy-link 中的第 1316 行,您可以更改 project.archivesBaseNamevariantData.variantConfiguration.baseName 以适应 unaligned-outputname。但我注意到这是否会与其他构建步骤混淆。不过,您不应该使用未对齐的版本,而应该使用最终的 apk(您可以完全控制其中的 apk 名称)。 (2) variant.name.capitalize()
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-12-26
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-04-25
                  相关资源
                  最近更新 更多