variantOutput.getPackageApplication() 已过时
variantOutput.getPackageApplication() is obsolete
随着 Gradle 4.10.1
和 Android Gradle 插件更新到 3.3.0
,我收到以下警告:
WARNING: API 'variantOutput.getPackageApplication()
' is obsolete and has been replaced with '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
时,我收到更多弃用警告(关键是,这些方法中的 none 被直接调用):
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 来避免这些弃用警告?
variantOutput.getPackageApplication() 是由变体 API.
引起的
changing output.outputFile.parent
to variant.getPackageApplicationProvider().get().outputs.files[1]
is at least a temporary workaround.
来源:@Selvin.
variant.getExternalNativeBuildTasks() 是由 io.fabric
插件引起的。
the next version of the io.fabric
plugin will use variant.getExternalNativeBuildProviders()
.
来源:116408637; the confirmation 承诺的修复 (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
None 其中 warnings
以任何方式改变行为。
我以前是这样写的:
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
}
}
}
}
如果您只是不想每次都弹出警告,这些可能会为您提供一些提示。
将 Fabric gradle 插件更新为 1.28.1
dependencies {
classpath 'io.fabric.tools:gradle:1.28.1'
}
变更日志:
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.
你可以使用更简单的,类似于这个例子:
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()
..
问题是 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
}
}
所以我遇到了同样的问题(截至该日期,运行 Gradle 5.4.1)。此外,我没有看到有效涵盖应用程序项目和库项目的答案。
因此,如果需要,我想制作一些理论上可以用于任何项目的东西,以便为整个项目制作一个 build.gradle。因为结果很好,所以我想我会添加它,以防有人想要同时适用于应用程序和库项目的东西。
编辑:
我 updated/optimized 自从最初发布这个方法以来。我现在正在使用 gradle 6.3 和 Kotlin DSL,下面的工作很顺利。
编辑2:
似乎在 Android Gradle build tools 4.1.0 (beta) 的某处他们默认禁用库项目的构建配置生成,所以我不得不更改一行以接受 null具有备份的值,更新如下。
/**
* 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
}
}
我没有在 gradle 中使用 output.outputFile.parent
。 variantOutput.getPackageApplication()
过时警告的原因是 dex 计数插件。我将它更新到 0.8.6 并且警告消失了。
'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.6'
以下警告的罪魁祸首是output.outputFile
WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.
要消除 Android Gradle 插件 3.4.0+ 的警告,您可以手动 assemble 输出路径为下面:
def selfAssembledOutputPath = new File("${project.buildDir.absolutePath}/outputs/apk/${variant.flavorName}/${variant.buildType.name}")
然后将下面的行替换为上面定义的 selfAssembledOutputPath
// this is the line:
outputFileName = selfAssembledOutputPath
您也可以使用旧版本的 gradle。我将我的 gradle 版本从 3.5.0 更改为 3.2.1 并且它有效。
不太狡猾的解决方案:
def variant = findYourVariantSomehow()
def output = findCorrectOutputInVariant(variant)
def fileName = output.outputFileName
def fileDir = variant.packageApplicationProvider.get().outputDirectory.get()
def apkFile = file("$fileDir/$fileName")
随着 Gradle 4.10.1
和 Android Gradle 插件更新到 3.3.0
,我收到以下警告:
WARNING: API '
variantOutput.getPackageApplication()
' is obsolete and has been replaced with '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
时,我收到更多弃用警告(关键是,这些方法中的 none 被直接调用):
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 来避免这些弃用警告?
variantOutput.getPackageApplication() 是由变体 API.
引起的changing
output.outputFile.parent
tovariant.getPackageApplicationProvider().get().outputs.files[1]
is at least a temporary workaround.
来源:@Selvin.
variant.getExternalNativeBuildTasks() 是由 io.fabric
插件引起的。
the next version of the
io.fabric
plugin will usevariant.getExternalNativeBuildProviders()
.
来源:116408637; the confirmation 承诺的修复 (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
None 其中 warnings
以任何方式改变行为。
我以前是这样写的:
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
}
}
}
}
如果您只是不想每次都弹出警告,这些可能会为您提供一些提示。
将 Fabric gradle 插件更新为 1.28.1
dependencies {
classpath 'io.fabric.tools:gradle:1.28.1'
}
变更日志: 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.
你可以使用更简单的,类似于这个例子:
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()
..
问题是 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
}
}
所以我遇到了同样的问题(截至该日期,运行 Gradle 5.4.1)。此外,我没有看到有效涵盖应用程序项目和库项目的答案。
因此,如果需要,我想制作一些理论上可以用于任何项目的东西,以便为整个项目制作一个 build.gradle。因为结果很好,所以我想我会添加它,以防有人想要同时适用于应用程序和库项目的东西。
编辑:
我 updated/optimized 自从最初发布这个方法以来。我现在正在使用 gradle 6.3 和 Kotlin DSL,下面的工作很顺利。
编辑2:
似乎在 Android Gradle build tools 4.1.0 (beta) 的某处他们默认禁用库项目的构建配置生成,所以我不得不更改一行以接受 null具有备份的值,更新如下。
/**
* 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
}
}
我没有在 gradle 中使用 output.outputFile.parent
。 variantOutput.getPackageApplication()
过时警告的原因是 dex 计数插件。我将它更新到 0.8.6 并且警告消失了。
'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.6'
以下警告的罪魁祸首是output.outputFile
WARNING: API 'variantOutput.getPackageApplication()' is obsolete and has been replaced with 'variant.getPackageApplicationProvider()'.
要消除 Android Gradle 插件 3.4.0+ 的警告,您可以手动 assemble 输出路径为下面:
def selfAssembledOutputPath = new File("${project.buildDir.absolutePath}/outputs/apk/${variant.flavorName}/${variant.buildType.name}")
然后将下面的行替换为上面定义的 selfAssembledOutputPath
// this is the line:
outputFileName = selfAssembledOutputPath
您也可以使用旧版本的 gradle。我将我的 gradle 版本从 3.5.0 更改为 3.2.1 并且它有效。
不太狡猾的解决方案:
def variant = findYourVariantSomehow()
def output = findCorrectOutputInVariant(variant)
def fileName = output.outputFileName
def fileDir = variant.packageApplicationProvider.get().outputDirectory.get()
def apkFile = file("$fileDir/$fileName")