32

随着 Gradle4.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()
            }
        }
    }
}

迁移指南不是很有帮助;虽然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 来避免这些弃用警告?

4

10 回答 10

15

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

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

资料来源:@Selvin


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

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

来源:116408637;对承诺修复的确认( 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()'

这篇博客文章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以任何方式改变行为。

于 2019-01-17T23:55:53.513 回答
9

将 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 警告。

于 2019-03-20T21:05:49.690 回答
2

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

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()
..
于 2019-04-29T22:51:03.920 回答
2

所以我遇到了同样的问题(截至目前,运行 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
    }
}
于 2019-06-19T21:41:38.220 回答
2

问题是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
    }
}
于 2019-05-16T08:22:47.857 回答
0

少一点狡猾的解决方案:

def variant = findYourVariantSomehow()
def output = findCorrectOutputInVariant(variant)
def fileName = output.outputFileName

def fileDir = variant.packageApplicationProvider.get().outputDirectory.get()

def apkFile = file("$fileDir/$fileName")

资源

于 2020-04-10T14:35:00.683 回答
0

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

'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.6'
于 2019-07-05T05:58:59.487 回答
0

以下警告的罪魁祸首是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
于 2019-07-31T02:11:25.363 回答
-1

您也可以使用旧版本的 gradle。我将我的 gradle 版本从 3.5.0 更改为 3.2.1 并且它有效。在此处输入图像描述

于 2019-09-20T20:17:27.547 回答
-1

我以前是这样写的:

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

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

于 2019-02-28T08:35:07.797 回答