问题
with Gradle 4.10.1 and the Android Gradle plugin updated to 3.3.0, I get the following warning:
WARNING: API \'
variantOutput.getPackageApplication()\' is obsolete and has been replaced with \'variant.getPackageApplicationProvider()\'.
the line, with the surrounding context (which is assigning output file-names by build variant):
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()
            }
        }
    }
}
the migration guide isn\'t too helpful; while the variant.outputs.all might be at fault - just have no clue with what to replace that - and the migration guide refers to tasks and not to build variants. when disabling File → Settings → Experimental → Gradle → Only sync the active variant, I get even more deprecation warnings (the point is, that none of these methods are being called directly):
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()\'.
Q: how can these deprecation warnings be avoided by migration to the new API?
回答1:
variantOutput.getPackageApplication() is being caused by a changed variant API.
changing
output.outputFile.parenttovariant.getPackageApplicationProvider().get().outputs.files[1]is at least a temporary workaround.
source: @Selvin.
variant.getExternalNativeBuildTasks() is being caused by the io.fabric plugin.
the next version of the
io.fabricplugin will usevariant.getExternalNativeBuildProviders().
source: 116408637; the confirmation for a promised fix (1.28.1).
These are caused by com.google.gms.google-services:
- registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
- 'variant.getMergeResources()' is obsolete and has been replaced with 'variant.getMergeResourcesProvider()'
This blog post explains how to get rid of the com.google.gms.google-services plugin altogether, by adding the XML resources, which that plugin generates, eg. from build/generated/res/google-services/debug/values/values.xml into the regular debug/values/values.xml.
The most easy and the least effort might be:
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"
    }
}
For debug information: ./gradlew -Pandroid.debug.obsoleteApi=true  mobile:assembleDebug
None of these warnings changes the behavior in any way.
回答2:
Update Fabric gradle plugin to 1.28.1
dependencies {
   classpath 'io.fabric.tools:gradle:1.28.1'
}
Changelog: https://docs.fabric.io/android/changelog.html#march-15-2019
Eliminated obsolete API warnings by switching to Gradle’s task configuration avoidance APIs, when available.
回答3:
You could use the simpler one, similar to this example:
applicationVariants.all { variant ->
            variant.outputs.all { output ->
                outputFileName = "${globalScope.project.name}-${variant.versionName}_${output.baseName}.apk"
            }
        }
and the result would be my_app-1.9.8_flavor1-release.apk.
In your code the problematic part (that generate the warning) is output.outputFile:
..
outputFileName = new File(output.outputFile.parent, fileName).getName()
..
回答4:
The problem is that output.outputFile is internally calling getPackageApplication()
I solved this problem by setting the directory and name of the output file myself.
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:
So I was getting the same issue (as of this date, running Gradle 5.4.1). Furthermore, I didn't see an answer that effectively covered both application projects as well as library projects.
Thus, I wanted to make something that could theoretically be used on any project to make a single build.gradle for the whole project, if desired. Because it turned out quite well, I figured I'd add it in case someone wants something that will work for both application and library projects.
The relevant part is here.
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)
        }
    }
}
Which simply calls the method below.
@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:
I used to wirite like this:
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
            }
        }
    }
}
The warning pop up each time, like open AS,sync,clean...
Then I found a way to write , it will just appear in build but will not pop up each time.
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
            }
        }
    }
}
If you just don't want the warning pop each time, these may have some tips for you.
回答7:
I wasn't using output.outputFile.parentin my gradle. The cause for variantOutput.getPackageApplication() obsolete warning was the dex count plugin. I updated it to 0.8.6 and warning is gone.
'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.6'
回答8:
The culprit of below warning is output.outputFile
WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.
To get rid of this warning for Android Gradle plugin 3.4.0+, you can manually assemble the output path as below:
def selfAssembledOutputPath = new File("${project.buildDir.absolutePath}/outputs/apk/${variant.flavorName}/${variant.buildType.name}")
Then replace your below line with selfAssembledOutputPath defined above
// this is the line:
outputFileName = selfAssembledOutputPath
回答9:
You can also use an older version of gradle. I changed my gradle version from 3.5.0 to 3.2.1 and it worked.
来源:https://stackoverflow.com/questions/54206898/variantoutput-getpackageapplication-is-obsolete