【问题标题】:android studio 3.1: build:gradle:3.1.0 - Absolute path are not supported when setting an output file nameandroid studio 3.1: build:gradle:3.1.0 - 设置输出文件名时不支持绝对路径
【发布时间】:2018-03-28 08:56:08
【问题描述】:

当我使用 Android Studio 3.0 并在 project/build.gradle 中使用下一版本的 Android Gradle Plugin 时:

classpath 'com.android.tools.build:gradle:3.0.1'

而且它工作正常。 在我更新到 Android Studio 3.1 后,我更新了 Android Gradle Plugin

classpath 'com.android.tools.build:gradle:3.1.0'

现在我的app/build.gradle 出现错误:

def releaseFileName = "${rootProject.name}_${defaultConfig.versionName}.apk"
outputFileName = new File(rootProject.projectDir.absolutePath + "/release", releaseFileName.toLowerCase())

错误:

设置输出文件名时不支持绝对路径

我需要将输出 apk (app-release.apk) 放在项目的特定路径中。在文件夹MyProject/release/app-relese.apk 中。我怎么能做到这一点?

【问题讨论】:

    标签: android-studio android-studio-3.0


    【解决方案1】:

    以防万一,此错误意味着现在不允许在与 apk 文件名相关的任何内容上使用绝对路径。我可以附上我的 BEFORE 和 AFTER 以实现我所需要的(在 project/app/build/ 文件夹中有 APK:

    在 gradle 3.1.0 之前

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            outputFileName = new File(
                    output.outputFile.parent,
                    output.outputFile.name)
        }
    }
    

    在 gradle 3.1.0 中或之后

    applicationVariants.all { variant ->
        variant.outputs.all { output ->
            outputFileName = new File(
                    "./../../../../../build/",
                    output.outputFile.name)
        }
    }
    

    【讨论】:

      【解决方案2】:

      我认为使用“./../../../”是不好的解决方案...我对几个项目使用通用 gradle 脚本,我想让代码独立于输出目录的深度。

      经过一番研究,我找到了 gradle plugin 3.1.2 的解决方案:

      applicationVariants.all { variant ->
          variant.outputs.all { output ->
              def relativeRootDir = output.packageApplication.outputDirectory.toPath()
                       .relativize(rootDir.toPath()).toFile()
              output.outputFileName = new File( "$relativeRootDir/release", newOutputName)
          }
      }
      

      【讨论】:

      【解决方案3】:

      Android Gradle 插件 3.4.0+ 最简单的解决方案如下:

      组装/连接您的新文件名:

      def newFileName = "assemble-your-new-file-name"
      

      然后,只需将其分配回去

      outputFileName = newFileName
      

      具体如下

      android.applicationVariants.all { variant ->
          variant.outputs.each { output ->
              // Redirect your apks to new defined location to outputDirPath
              def outputDirPath = new File("${project.rootDir.absolutePath}/apks/${variant.flavorName}/${variant.buildType.name}")
              variant.packageApplicationProvider.get().outputDirectory = outputDirPath
      
              def apkFileName = "${rootProject.name}_${android.defaultConfig.versionName}.apk"
              output.outputFileName = apkFileName // directly assign the new name back to outputFileName
          }
      }
      

      【讨论】:

      • 获取输出 apk 文件名/路径而不是输出目录的最佳方法是什么?
      • @DavidBerry, output.outputFileName 是 apk 文件名。但是,我不确定这是否是最好的方法。
      • 至少在 5.1.1 outputFileName 给出未知属性错误。
      • @DavidBerry,outputFileName 是 Android Gradle 插件属性,而不是 Gradle 内置属性。目前插件版本为3.4.2,对应的Gradle版本为5.+。至少对我来说,这个工具集很好用。
      • 查看stackoverflow.com/a/51392464/8034839了解有关版本的更多信息
      【解决方案4】:

      我遇到了同样的问题。我还没有努力弄清楚到底发生了什么,但有一个简单的解决方法。

      只需从新文件中删除根并信任框架,即将代码更改为

      outputFileName = new File("release", releaseFileName.toLowerCase())
      

      这对我们来说已经足够了。我们不关心 apk 的去向,只关心特定风格的 apk 名称。

      【讨论】:

      • 我需要将输出 apk (app-release.apk) 放在项目的特定路径中。在文件夹 MyProject/release/app-relese.apk 中。我该怎么做?
      • 抱歉,这里的深度不够。我需要设置 gradle 调试和/或进入源代码来解决这个问题。我的猜测是有一些方法可以将您的路径转换为相对于项目根目录的路径。我不知道为什么要强制执行此更改并且似乎没有记录在案。看起来你至少有自己的解决方法:)
      【解决方案5】:

      我找到了解决方案:

      def releaseFileName = "${rootProject.name}_${defaultConfig.versionName}.apk"
      outputFileName = "/../../../../../release/" + releaseFileName.toLowerCase()
      

      现在输出文件app-release.apkMyProject/release/app-relese.apk中创建成功

      【讨论】:

        【解决方案6】:

        使用variant.packageApplicationProvider.get().outputDirectory 避免警告“variantOutput.getPackageApplication() 已过时

        applicationVariants.all { variant ->
            variant.outputs.each { output ->
                variant.packageApplicationProvider.get().outputDirectory = new File(
                    project.rootDir.absolutePath + "/release")
        
                def releaseFileName = "${rootProject.name}_${defaultConfig.versionName}.apk"
                output.outputFileName = releaseFileName.toLowerCase()
            }
        }
        

        【讨论】:

          【解决方案7】:

          对于 gradle-6.5.1:

          applicationVariants.all { variant ->
                    variant.outputs.all { output ->
                            outputFileName = new File("ApkName.apk")
                    }
           }
          

          【讨论】:

            【解决方案8】:

            如果要附加版本名称和版本代码,请执行以下操作:

            applicationVariants.all { variant ->
                    variant.outputs.all {
                        def versionName = variant.versionName
                        def versionCode = variant.versionCode
                        def variantName = variant.name
                        outputFileName = "${rootProject.name}" + '_' + variantName + '_' + versionName + '_' + versionCode + '.apk'
                    }
                }
            

            【讨论】:

              猜你喜欢
              • 2019-04-11
              • 1970-01-01
              • 2011-12-17
              • 2021-11-24
              • 1970-01-01
              • 2021-07-28
              • 2018-08-22
              • 2021-03-04
              • 2020-06-04
              相关资源
              最近更新 更多