Android Studio升级至v3.3,获得API';variant.getAssembly()和#x27;已过时,并已替换为';variant.getAssembleProvider()';

Android Studio升级至v3.3,获得API';variant.getAssembly()和#x27;已过时,并已替换为';variant.getAssembleProvider()';,android,android-studio,gradle,gradle-plugin,Android,Android Studio,Gradle,Gradle Plugin,获取此警告(即使在任何地方都未使用variant.getAssembly()时): 我已更新了以下组件: 安卓工作室 v3.3 渐变插件 v3.3 Gradle分发URL(Gradle wrapper.properties) distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip 格拉德尔酒店 android.debug.obsoleteApi=true 如果使用的某个库是您的项目正在使用此

获取此警告(即使在任何地方都未使用
variant.getAssembly()
时):

我已更新了以下组件: 安卓工作室

v3.3

渐变插件

v3.3

Gradle分发URL
(Gradle wrapper.properties)

distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip

格拉德尔酒店

android.debug.obsoleteApi=true


如果使用的某个库是您的项目正在使用此方法的临时解决方案,则会出现此类警告
-编辑根目录“build.gradle”文件。
-将“com.android.tools.build:gradle:3.3.0”更改为“3.2.0”
完成了

同样的问题:

看看这个:


这是一个警告,它不会对您的构建产生负面影响。您可以前进并更新到AGP 3.3.0

新的Android Gradle插件开始利用惰性配置(任务配置避免API和提供者API),如果使用得当,只需评估所需的任务和属性,就可以提高构建速度。AGP的使用者需要使用更新的API(例如,
getAssembleProvider().configure()
而不是
getAssemble()
),否则任务和属性总是会被评估

惰性API的要点:不要配置在特定构建中不会运行的任务

阅读更多:

怎么办 如果它不是来自您的代码,那么除了等待更新的库之外,您无需做任何事情(并祈祷他们做得对)

如果它来自您的代码,下面是一个迁移示例:我使用Jake Wharton的这段代码来禁用库模块的
BuildConfig.java
生成

libraryVariants.all {
    it.generateBuildConfig.enabled = false
}
使用新的lazyapi,它看起来是这样的

libraryVariants.all {
    it.generateBuildConfigProvider.configure {
        it.enabled = false
    }
}
即使我不需要,
generateBuildConfig
任务也会被配置,例如运行
clean
。只有当任务是要运行的任务图的一部分时,lazy API才会配置该任务。这节省了配置阶段的时间

如何确定它是否来自您的代码?将其放入您的
gradle.properties

android.debug.obsoleteApi=true
现在运行构建并检查堆栈跟踪的输出

完全错误 为完整起见,下面是一个由结构插件1.27.0和AGP 3.3.0引起的完整错误消息示例:

WARNING: API 'variant.getExternalNativeBuildTasks()' is obsolete and has been replaced with 'variant.getExternalNativeBuildProviders()'.
It will be removed at the end of 2019.
For more information, see https://d.android.com/r/tools/task-configuration-avoidance.
To determine what is calling variant.getExternalNativeBuildTasks(), use -Pandroid.debug.obsoleteApi=true on the command line to display a stack trace.
坏榜样 以下是Facebook React如何在其插件中处理API迁移的差异:

换句话说,他们没有
taskProvider.get()
等于
task
——这两种用法都很有用。任务始终处于配置状态

这种方法实现的唯一一件事就是删除警告

  • 消费者不知道他们没有从懒惰的API中获得任何好处
  • 插件作者不再被提醒他们用错了

包含一个迁移指南和一个有用的表,描述如何创建和链接任务。如果您是插件作者,请阅读。

variant.Assembly已被弃用,并被新的提供程序API取代

例如,如果您将其用作下一个:

variant.outputs.all { output ->
        variant.assemble.doLast {
            ....
        }
    }
}
然后将其替换为新的提供程序API:

variant.outputs.all { output ->
    variant.getAssembleProvider().configure() {
        it.doLast { 
            ....
        }
    }
}

我也有同样的警告

这是我的应用程序级gradle文件:

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
    applicationId 'com.lauszus.facerecognitionapp'
    minSdkVersion 16
    targetSdkVersion 28
    versionCode 6
    versionName '1.2.3'
    vectorDrawables.useSupportLibrary = true
    ndk {
        stl 'c++_static'
        cFlags '-std=gnu++11 -fexceptions -frtti -DANDROID_STL=c++_static'
    }
    setProperty('archivesBaseName', rootProject.name + '-' + defaultConfig.versionName)
}
splits {
    abi {
        enable true
        reset()
        universalApk true
        include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
    }
}
project.ext.abiCodes = ['armeabi-v7a':1, 'arm64-v8a':2, 'x86':3, 'x86_64':4]
applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def baseAbiVersionCode = project.ext.abiCodes.get(output.getFilter(com.android.build.OutputFile.ABI))
        // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
        // the following code does not override the version code for universal APKs.
        if (baseAbiVersionCode != null) {
            output.versionCodeOverride = baseAbiVersionCode * 1000000 + variant.versionCode
        }
    }
    if (variant.getBuildType().isMinifyEnabled()) {
        variant.assemble.doLast {
            variant.mappingFile.renameTo(variant.mappingFile.parent +
                    "/$archivesBaseName-$variant.baseName-mapping.txt")
        }
    }
}
signingConfigs {
    release
}
buildTypes {
    debug {
        jniDebuggable true
        externalNativeBuild {
            ndkBuild {
                arguments 'NDK_DEBUG=1', 'NDEBUG=null'
            }
        }
    }
    release {
        shrinkResources true
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        signingConfig signingConfigs.release
    }
}
externalNativeBuild {
    ndkBuild {
        path 'src/main/cpp/Android.mk'
    }
}
lintOptions {
    abortOnError false
}
 }

 dependencies {

   implementation 'com.android.support:appcompat-v7:28.0.0'
   implementation 'com.android.support:design:28.0.0'
   implementation project(':opencv')

  }

 // These values are all set in my global gradle.properties file
 if (project.hasProperty('storeFile') && project.hasProperty('storePassword') && 
  project.hasProperty('keyAlias') && project.hasProperty('keyPassword')) {
  android.signingConfigs.release.storeFile = file(storeFile)
  android.signingConfigs.release.storePassword = storePassword
  android.signingConfigs.release.keyAlias = keyAlias
  android.signingConfigs.release.keyPassword = keyPassword
} else {
android.buildTypes.release.signingConfig = null
}
如果您的应用程序级别的gradle文件包含variant.assemble.doLast块,则;尝试将“
variant.assembly.doLast
”更改为“
variant.assembleProvider.get().doLast

像这样:

 if (variant.getBuildType().isMinifyEnabled()) {
        variant.assembleProvider.get().doLast {   //HERE
            variant.mappingFile.renameTo(variant.mappingFile.parent +
                    "/$archivesBaseName-$variant.baseName-mapping.txt")
        }
    }
    android.applicationVariants.all { variant ->

    variant.assemble.doLast {

web链接。

检查您的应用程序级别。或者在它里面应用gradle。进行了如下更改

原件:

 if (variant.getBuildType().isMinifyEnabled()) {
        variant.assembleProvider.get().doLast {   //HERE
            variant.mappingFile.renameTo(variant.mappingFile.parent +
                    "/$archivesBaseName-$variant.baseName-mapping.txt")
        }
    }
    android.applicationVariants.all { variant ->

    variant.assemble.doLast {
修复后:

android.applicationVariants.all { variant ->

    variant.assembleProvider.get().doLast {

这只是一个警告。你只能通过更新来获得:那么,你的问题是什么?这正是你不应该做的。这两个代码示例都是等效的,这意味着您根本得不到任何好处。调用
Provider.get()
时,即使没有其他人需要它,也会导致求值。lazyconfigapi的全部要点是不要准备从未使用过的东西。示例:如果我只调用
gradlew clean
,我不需要设置输出。您似乎不明白答案。说明的是从现在起必须使用提供者。“示例”适用于需要输出的特定情况,显示了如何通过提供程序而不是旧API进行相同的调用。1)您只是隐藏了错误消息,但问题仍然存在。2) 旧的API未被删除,仍在运行。版本3.3.0不是主要版本-不允许删除。错误消息明确表示,旧API将在2019年底被删除。3)
variant.getAssembly()
等于
variant.getAssembleProvider().get()
。两人都很渴望。您应该调用
variant.getAssembleProvider().configure{…}
,它将仅在评估任务时执行
configure
块。请参见此处了解其外观:您可以在此处阅读有关任务配置避免的更多信息:感谢链接,很好地澄清了这一点。我已经根据文档内容更新了答案,因为这对我也很有用。请添加您认为可能需要的任何注释。我认为,如果您用更多的例子来扩展您的答案,这将是一个好主意,因为这是一个新的变化,没有多少开发人员不知道如何正确处理。