variantOutput.getPackageApplication() 已过时
Posted
技术标签:
【中文标题】variantOutput.getPackageApplication() 已过时【英文标题】:variantOutput.getPackageApplication() is obsolete 【发布时间】: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-services
的registerResGeneratingTask is deprecated, use registerGeneratedResFolders(FileCollection)
相同...我放弃了...我花了 2 天时间分析这些警告
【参考方案1】:
variantOutput.getPackageApplication() 是由更改的变体 API 引起的。
将
output.outputFile.parent
更改为variant.getPackageApplicationProvider().get().outputs.files[1]
至少是一种临时解决方法。
来源:@Selvin。
variant.getExternalNativeBuildTasks() 是由io.fabric
插件引起的。
io.fabric
插件的下一个版本将使用variant.getExternalNativeBuildProviders()
。
来源:116408637; 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
这些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.parent
。 variantOutput.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 服务插件,它几乎没有任何警告。以上是关于variantOutput.getPackageApplication() 已过时的主要内容,如果未能解决你的问题,请参考以下文章