【问题标题】:variantOutput.getPackageApplication() is obsoletevariantOutput.getPackageApplication() 已过时
【发布时间】:2019-06-09 22:33:08
【问题描述】:

使用 Gradle 4.10.1 并将 Android Gradle 插件更新为 3.3.0,我收到以下警告:

警告:API“variantOutput.getPackageApplication()”已过时,已被“variant.getPackageApplicationProvider()”取代。

带有周围上下文的行(通过构建变体分配输出文件名):

applicationVariants.all { variant ->
    variant.outputs.all { output ->

        if (variant.getBuildType().getName() in rootProject.archiveBuildTypes) {

            def buildType = variant.getBuildType().getName()
            if (variant.versionName != null) {

                def baseName = output.baseName.toLowerCase()
                String fileName = "${rootProject.name}_${variant.versionName}-${baseName}.apk"

                // this is the line:
                outputFileName = new File(output.outputFile.parent, fileName).getName()
            }
        }
    }
}

migration guide 不太有用;虽然variant.outputs.all 可能有问题——只是不知道用什么替换它——而迁移指南指的是任务而不是构建变体。禁用File → Settings → Experimental → Gradle → Only sync the active variant 时,我会收到更多弃用警告(关键是,这些方法都没有被直接调用):

WARNING: API 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'.
WARNING: API 'variantOutput.getProcessResources()' is obsolete and has been replaced with 'variantOutput.getProcessResourcesProvider()'.
WARNING: API 'variantOutput.getProcessManifest()' is obsolete and has been replaced with 'variantOutput.getProcessManifestProvider()'.
WARNING: API 'variant.getMergeResources()' is obsolete and has been replaced with 'variant.getMergeResourcesProvider()'.
WARNING: API 'variant.getMergeAssets()' is obsolete and has been replaced with 'variant.getMergeAssetsProvider()'.
WARNING: API 'variant.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.
WARNING: API 'variant.getExternalNativeBuildTasks()' is obsolete and has been replaced with 'variant.getExternalNativeBuildProviders()'.
WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.

问:如何通过迁移到新 API 来避免这些弃用警告?

【问题讨论】:

  • output.outputFile.parent => variant.getPackageApplicationProvider().get().outputs.files[1] .... google 应该修复它,因为问题是 output.outputFile 它在内部调用 getPackageApplication()
  • @Selvin 这至少修复了一个警告;然后它抱怨:variant.getExternalNativeBuildTasks() 已过时...需要替换为variant.getExternalNativeBuildProviders()
  • 呵呵variant.getExternalNativeBuildProviders() 这来自...。让我猜猜... io.fabric 插件...
  • @Selvin 你是对的;启用调试后,提示:com.crashlytics.tools.gradle.ProjectVariantState.resolveDebugNativeLibsPath(ProjectVariantState.groovy:130)。添加评论作为答案,我会接受它,因为它回答了主要问题。
  • 所以...这都是 Google 的错...与来自com.google.gms.google-servicesregisterResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection) 相同...我放弃了...我花了 2 天时间分析这些警告

标签: gradle android-gradle-plugin build.gradle deprecation-warning build-variant


【解决方案1】:

variantOutput.getPackageApplication() 是由更改的变体 API 引起的。

output.outputFile.parent 更改为variant.getPackageApplicationProvider().get().outputs.files[1] 至少是一种临时解决方法。

来源:@Selvin


variant.getExternalNativeBuildTasks() 是由io.fabric 插件引起的。

io.fabric 插件的下一个版本将使用variant.getExternalNativeBuildProviders()

来源:116408637confirmation 承诺修复 (1.28.1)。


这些都是com.google.gms.google-services引起的:

  • registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)

  • 'variant.getMergeResources()' is obsolete and has been replaced with 'variant.getMergeResourcesProvider()'

这个blog post 解释了如何完全摆脱com.google.gms.google-services 插件,通过添加该插件生成的XML 资源,例如。从build/generated/res/google-services/debug/values/values.xml 到常规的debug/values/values.xml


最简单、最省力的可能是:

buildscript {
    repositories {
        google()
        maven { url "https://maven.fabric.io/public" }
    }
    dependencies {
        //noinspection GradleDependency
        classpath "com.android.tools.build:gradle:3.2.1"
        classpath "io.fabric.tools:gradle:1.28.1"
    }
}

调试信息:./gradlew -Pandroid.debug.obsoleteApi=true mobile:assembleDebug

这些warnings 都不会以任何方式改变行为。

【讨论】:

  • 我猜是和他们的插件有关,我们真的无能为力。
  • 在我的例子中是dexcount gradle 插件。在我将其升级到版本0.8.6 后,警告消失了。
  • @IlyaEremin 可能有各种插件仍在使用这些方法。
  • @@martim zeitler。我有同样的问题,但我没有使用织物插件
  • @Ggriffo 很可能是其他插件使用了已弃用的 API。
【解决方案2】:

将 Fabric gradle 插件更新到 1.28.1

dependencies {
   classpath 'io.fabric.tools:gradle:1.28.1'
}

变更日志: https://docs.fabric.io/android/changelog.html#march-15-2019

通过切换到 Gradle 的任务配置避免 API(如果可用)来消除过时的 API 警告。

【讨论】:

    【解决方案3】:

    你可以使用更简单的,类似于这个例子:

    applicationVariants.all { variant ->
                variant.outputs.all { output ->
                    outputFileName = "${globalScope.project.name}-${variant.versionName}_${output.baseName}.apk"
                }
            }
    

    结果将是my_app-1.9.8_flavor1-release.apk

    在您的代码中,有问题的部分(生成警告)是output.outputFile

    ..
    outputFileName = new File(output.outputFile.parent, fileName).getName()
    ..
    

    【讨论】:

      【解决方案4】:

      问题是output.outputFile在内部调用getPackageApplication()

      我通过自己设置输出文件的目录和名称解决了这个问题。

      applicationVariants.all { variant ->
          variant.outputs.each { output ->
              def outputDir = new File("${project.buildDir.absolutePath}/outputs/apk/${variant.flavorName}/${variant.buildType.name}")
              def outputFileName = "app-${variant.flavorName}-${variant.buildType.name}.apk"
              // def outputFile = new File("$outputDir/$outputFileName")
      
              variant.packageApplicationProvider.get().outputDirectory = new File("$outputDir")
              output.outputFileName = outputFileName
          }
      }
      

      【讨论】:

        【解决方案5】:

        所以我遇到了同样的问题(截至目前,运行 Gradle 5.4.1)。此外,我没有看到有效涵盖应用程序项目和库项目的答案。

        因此,如果需要,我想制作理论上可以用于任何项目的东西,以便为整个项目制作单个 build.gradle。因为结果非常好,我想我会添加它,以防有人想要一些适用于应用程序和库项目的东西。

        编辑:

        自从最初发布它以来,我已经更新/优化了这个方法。我现在正在使用带有 Kotlin DSL 的 gradle 6.3,并且以下工作正常。

        编辑2:

        似乎在 Android Gradle 构建工具 4.1.0(测试版)的某个地方,它们默认禁用库项目的构建配置生成,因此我不得不更改一行以接受带有备份的空值,更新如下。

        /**
         * Configures the output file names for all outputs of the provided variant. That is, for
         * the provided application or library.
         *
         * @param variant Passed in with {android.defaultConfig.applicationVariants.all.this}
         * @param project The project from which to grab the filename. Tip: Use rootProject
         * @param formatString Format string for the filename, which will be called with three 
         * arguments: (1) Project Name, (2) Version Name, (3) Build Type. ".apk" or ".aar" is 
         * automatically appended. If not provided, defaults to "%1$s-%2$s_%3$s"
         */
        @SuppressWarnings("UnnecessaryQualifiedReference")
        fun configureOutputFileName(
            variant: com.android.build.gradle.api.BaseVariant,
            project: Project,
            formatString: String = "%1\$s-%2\$s_%3\$s"
        ) {
            variant.outputs.configureEach {
                val fileName = formatString.format(project.name,
                    outputVariant.generateBuildConfigProvider.orNull?.versionName?.orNull ?:
                        project.version, variant.buildType.name)
                val tmpOutputFile: File = when (variant) {
                    is com.android.build.gradle.api.ApplicationVariant -> 
                        File(variant.packageApplicationProvider!!.get().outputDirectory.asFile
                            .get().absolutePath,"$fileName.apk")
                    is com.android.build.gradle.api.LibraryVariant -> 
                        File(variant.packageLibraryProvider!!.get().destinationDirectory.asFile
                            .get().absolutePath,"$fileName.aar")
                    else -> outputFile
                }
                (this as com.android.build.gradle.internal.api.BaseVariantOutputImpl)
                    .outputFileName = tmpOutputFile.name
                println("Output file set to \"${tmpOutputFile.canonicalPath}\"")
            }
        }
        

        原文:

        相关部分在这里。

        android {
            if (it instanceof com.android.build.gradle.AppExtension) {
                it.applicationVariants.all { 
                    com.android.build.gradle.api.ApplicationVariant variant ->
                        configureOutputFileName(variant, project)
                }
            } else if (it instanceof com.android.build.gradle.LibraryExtension) {
                it.libraryVariants.all { com.android.build.gradle.api.LibraryVariant variant ->
                    configureOutputFileName(variant, project)
                }
            }
        }
        

        简单地调用下面的方法。

        @SuppressWarnings("UnnecessaryQualifiedReference")
        private void configureOutputFileName(com.android.build.gradle.api.BaseVariant variant,
            Project project) {
            variant.outputs.all { output ->
                def buildType = variant.buildType.name
                String tmpOutputFileName = outputFileName
                if (variant instanceof com.android.build.gradle.api.ApplicationVariant) {
                    String fileName = "${project.name}-${variant.versionName}_${buildType}.apk"
                    def defaultOutputDir = variant.packageApplicationProvider.get().outputDirectory
                    tmpOutputFileName = new File(defaultOutputDir.absolutePath, fileName).name
                }
                if (variant instanceof com.android.build.gradle.api.LibraryVariant) {
                    String fileName = "${project.name}_${buildType}.aar"
                    def defaultOutputDir = variant.packageLibraryProvider.get()
                        .destinationDirectory.asFile.get()
                    tmpOutputFileName = new File(defaultOutputDir.absolutePath, fileName).name
                }
                println(tmpOutputFileName)
                outputFileName = tmpOutputFileName
            }
        }
        

        【讨论】:

          【解决方案6】:

          我没有在我的 gradle 中使用 output.outputFile.parentvariantOutput.getPackageApplication() 过时警告的原因是 dex 计数插件。我将它更新到 0.8.6 并且警告消失了。

          'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.6'
          

          【讨论】:

            【解决方案7】:

            以下警告的罪魁祸首是output.outputFile

            警告:API 'variantOutput.getPackageApplication()' 已过时,已替换为 'variant.getPackageApplicationProvider()'。

            为了摆脱Android Gradle插件3.4.0+的这个警告,你可以手动组装输出路径如下:

            def selfAssembledOutputPath = new File("${project.buildDir.absolutePath}/outputs/apk/${variant.flavorName}/${variant.buildType.name}")
            

            然后将下面的行替换为上面定义的selfAssembledOutputPath

            // this is the line:
            outputFileName = selfAssembledOutputPath
            

            【讨论】:

              【解决方案8】:

              不那么狡猾的解决方案:

              def variant = findYourVariantSomehow()
              def output = findCorrectOutputInVariant(variant)
              def fileName = output.outputFileName
              
              def fileDir = variant.packageApplicationProvider.get().outputDirectory.get()
              
              def apkFile = file("$fileDir/$fileName")
              

              source

              【讨论】:

                【解决方案9】:

                我以前是这样写的:

                android.applicationVariants.all { variant ->
                    if ("release" == variant.buildType.name) {
                        variant.outputs.all { output ->
                            outputFileName = output.outputFile.name.replace("-release", "")
                        }
                        variant.assemble.doLast {
                            variant.outputs.all { output ->
                                delete output.outputFile.parent + "/output.json"
                                copy {
                                    from output.outputFile.parent
                                    into output.outputFile.parentFile.parent
                                }
                                delete output.outputFile.parent
                            }
                        }
                    }
                }
                

                每次都会弹出警告,比如open AS,sync,clean...

                然后我找到了一种写法,它只会出现在构建中,但不会每次都弹出。

                android.applicationVariants.all { variant ->
                    if ("release" == variant.buildType.name) {
                        assembleRelease.doLast {
                            variant.outputs.all { output ->
                                delete output.outputFile.parent + "/output.json"
                                copy {
                                    from output.outputFile.parent
                                    into output.outputFile.parentFile.parent
                                    rename { filename ->
                                        filename.replace("-release", "")
                                    }
                                }
                                delete output.outputFile.parent
                            }
                        }
                    }
                }
                

                如果您只是不想每次都弹出警告,这些可能会为您提供一些提示。

                【讨论】:

                  【解决方案10】:

                  您也可以使用旧版本的 gradle。我将我的 gradle 版本从 3.5.0 更改为 3.2.1,它工作正常。

                  【讨论】:

                  • 这仅取决于 Gradle 版本。同时,使用最新的 Fabric 和 Google Play 服务插件,它几乎没有任何警告。
                  猜你喜欢
                  • 2019-09-21
                  • 2019-05-30
                  • 1970-01-01
                  • 2011-04-26
                  • 2018-05-01
                  • 2011-08-02
                  • 2011-10-10
                  • 2015-09-30
                  • 2018-05-31
                  相关资源
                  最近更新 更多