While Android Studio Updated to v3.3 getting API 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'
Asked Answered
I

6

13

Getting this Warning (Even when variant.getAssemble() is not used anywhere):

API 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'.

I have updated following components: Android Studio

v3.3

Gradle PlugIn

v3.3

Gradle Distribution URL (gradle-wrapper.properties)

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

gradle.properties

android.debug.obsoleteApi=true

Interference answered 15/1, 2019 at 6:7 Comment(1)
So, what's your question?Leandroleaning
I
23

variant.assemble has been deprecated and replaced by a new provider API.

If for example you are using it as next:

variant.outputs.all { output ->
        variant.assemble.doLast {
            ....
        }
    }
}

Then replace it the new provider API:

variant.outputs.all { output ->
    variant.getAssembleProvider().configure() {
        it.doLast { 
            ....
        }
    }
}
Isopiestic answered 1/2, 2019 at 13:42 Comment(5)
This is exactly what you're not supposed to do. Both of these code samples are equivalent, meaning you get no benefit at all. When you call Provider.get() you cause the evaluation even if nobody else needed it. The whole point of lazy config API is to not prepare stuff that's never used. Example: I don't need to setup outputs if I only call gradlew clean.Leandroleaning
Seems you didn't understand the answer. What states is that from now on providers must be used. And the "example" is for a particular case where outputs are needed, showing how to make the same call but through a provider instead of the old API.Isopiestic
1) You just hid the error message, but the problem remains. 2) The old API isn't removed and is still working. Version 3.3.0 is not a major release - no removals allowed. And the error message specifically says the old API will be removed at the end of 2019. 3) variant.getAssemble() equals variant.getAssembleProvider().get(). Both are eager. You're supposed to call variant.getAssembleProvider().configure { ... }, which will only execute the configure block when and if the task is evaluated. See here for how it's supposed to look: pastebin.com/SC2HY3CBLeandroleaning
You can read more about Task Configuration Avoidance here: docs.gradle.org/current/5.1.1/task_configuration_avoidance.htmlLeandroleaning
Thanks for the link, was very good to clarify it. I've updated the answer according on how it should be based on the documentation, as this is quite useful for me too. Please add any notes you think it may require. I think it would be a good idea if you extended your answer with a few more examples, as this is a new change that not many developers will not how to handle correctly.Isopiestic
L
5

It's a warning, it doesn't negatively impact your build. You may go forward and update to AGP 3.3.0.

The new Android Gradle Plugin started leveraging lazy configuration (Task Configuration Avoidance API and Provider API) which, if used properly, may improve build speeds by only evaluating tasks and properties which are needed. Consumers of AGP need to use the updated API (e.g. getAssembleProvider().configure() instead of getAssemble()) otherwise the tasks and properties are always evaluated.

The point of lazy API: Don't configure tasks which aren't going to run in a particular build.

Read more:

What to do

If it's not coming from your code there's nothing for you to do other than wait for updated libraries (and pray they do it right).

If it comes from your code, here's an example of migration: I'm using this bit of code from Jake Wharton to disable BuildConfig.java generation for my library modules.

libraryVariants.all {
    it.generateBuildConfig.enabled = false
}

Using the new lazy API it looks like this.

libraryVariants.all {
    it.generateBuildConfigProvider.configure {
        it.enabled = false
    }
}

The eager API would cause the generateBuildConfig task to be configured even if I didn't need it, such as running clean. The lazy API configures the task only if it's part of the task graph to run. This saves time during the configuration phase.

How to figure out if it comes from your code? Put this in your gradle.properties

android.debug.obsoleteApi=true

Now run a build and check the output for stack traces.

Full error

For completeness, here's an example of a full error message caused by the Fabric plugin 1.27.0 with 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.

Bad example

Here's a diff of how Facebook React dealt with the API migration in their plugin: https://github.com/facebook/react-native/pull/23103/files

In other words, they didn't. taskProvider.get() is equal to task - both uses are eager. The tasks are always configured.

The only thing this approach achieves is removing the warning so

  • the consumer has no idea they're not getting any benefits of the lazy API,
  • the plugin author is no longer reminded they're using it wrong.

The Task Configuration Avoidance API docs contain a migration guide and a helpful table describing how to create and chain tasks lazily. If you're a plugin author, please read it.

Leandroleaning answered 24/1, 2019 at 9:45 Comment(0)
P
3

I had the same Warning!!

And this is my app level gradle file:

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
}

If your app level gradle file contains variant.assemble.doLast block then; Try changing “variant.assemble.doLast” to “variant.assembleProvider.get().doLast

like this:

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

referred web link.

Psycholinguistics answered 29/8, 2019 at 11:52 Comment(0)
I
2

This type of warning can appear if some library used is your project is using this method

Iotacism answered 15/1, 2019 at 7:44 Comment(0)
B
1

Check your app level gradle. or applied gradle in it. made changes like below

Original :

    android.applicationVariants.all { variant ->

    variant.assemble.doLast {

After Fix :

android.applicationVariants.all { variant ->

    variant.assembleProvider.get().doLast {
Bastardy answered 8/5, 2020 at 6:41 Comment(0)
E
0

Temporary solution!
- Edit your root "build.gradle" file.
- Change "com.android.tools.build:gradle:3.3.0" to "3.2.0"
Done.

same problem:

https://mcmap.net/q/127062/-warning-api-39-variant-getjavacompile-39-is-obsolete-and-has-been-replaced-with-39-variant-getjavacompileprovider-39

and see this:

https://mcmap.net/q/130799/-unexpected-gradle-warnings-code-editor-breakdown

Evangelista answered 24/1, 2019 at 9:22 Comment(1)
It's just a warning. You can only gain by updating: developer.android.com/studio/releases/gradle-pluginLeandroleaning

© 2022 - 2024 — McMap. All rights reserved.