Mobile Dev

Resolve Invoke-customs Error After Gradle Update

Fix the 'Invoke-customs are only supported starting with Android 0 --min-api 26' error after updating Gradle build tools and Java compatibility in Android Studio.

1 answer 1 view

How to resolve the ‘Invoke-customs are only supported starting with Android 0 --min-api 26’ error after updating Gradle build tools version from 26 to 27 and changing Java compatibility settings to use Kotlin version compatibility in Android Studio?

When updating Gradle build tools from version 26 to 27 and modifying Java compatibility settings in Android Studio, you may encounter the “Invoke-customs are only supported starting with Android 0 --min-api 26” error. This occurs when your compiled bytecode contains invoke-custom instructions but your minimum SDK version is below 26, which happens when using newer Java features with Kotlin in older Android API levels. To resolve this, you can either raise your minimum SDK version to 26+ or enable core library desugaring in your Gradle configuration.


Contents


Understanding the “Invoke-customs are only supported starting with Android 0 --min-api 26” Error

The “Invoke-customs are only supported starting with Android 0 --min-api 26” error is a compatibility warning that appears in your Android Studio build log when the compiled bytecode contains invoke-custom instructions but the minimum SDK version in your AndroidManifest.xml is set to a value below 26. This happens specifically after updating Gradle build tools from version 26 to 27 and adjusting Java compatibility settings to align with Kotlin version requirements.

What’s happening here is that your code, likely written in Kotlin with modern language features, gets compiled to bytecode that uses newer Java bytecode instructions. These instructions aren’t supported by Android’s runtime environment on API levels below 26. The Android build system is warning you that your app won’t function correctly on devices running Android versions older than 8.0 (Oreo, API 26) unless you make specific configuration changes.

This error is particularly common when working with Kotlin in Android Studio because Kotlin often uses modern Java features that compile to these invoke-custom instructions. When you update your Gradle build tools and adjust Java compatibility settings to match your Kotlin version, you’re essentially enabling these newer language features, which then trigger this compatibility warning.


Root Causes After Gradle Build Tools Update to Version 27

Several factors contribute to this error specifically after updating from Gradle build tools version 26 to 27 and adjusting Java compatibility settings for Kotlin:

Java Version Compatibility Changes: When you update your Java compatibility settings to match your Kotlin version (often Java 11 or higher for modern Kotlin versions), you enable newer Java language features. These features compile to bytecode that uses invoke-custom instructions, which Android’s runtime doesn’t support on API levels below 26.

Kotlin Language Features: Kotlin 1.5+ introduced several language features that generate invoke-custom instructions, such as inline classes, value classes, and certain type-safe builders. When these features are used with a minimum SDK version below 26, the build system generates this warning.

Gradle Plugin Behavior Changes: The Android Gradle Plugin behavior changed in version 27 to be more strict about bytecode compatibility. It now explicitly checks for invoke-custom instructions and warns about their use with lower API levels, whereas previous versions might have silently allowed this.

Default Configuration Mismatches: When updating Gradle build tools, the default configuration settings may not automatically align with your project’s minimum SDK version. This creates a mismatch where the build system expects certain bytecode features but can’t support them on your target Android versions.

Understanding these root causes helps you choose the appropriate solution based on your project’s requirements. If your app needs to support older Android devices, you’ll need to use core library desugaring. If you’re targeting modern devices only, raising the minimum SDK version is the simpler approach.


Solution 1: Raising the Minimum SDK Version to 26+

The most straightforward solution to resolve the “Invoke-customs are only supported starting with Android 0 --min-api 26” error is to update your minimum SDK version to 26 or higher. This approach is ideal if your app doesn’t need to support Android versions older than 8.0 (Oreo).

To implement this solution, you need to modify two key files in your Android Studio project:

app/build.gradle (Module: app):

gradle
android {
 compileSdk 34
 
 defaultConfig {
 applicationId "com.yourapp"
 minSdk 26 // Change from a lower value like 21 to 26
 targetSdk 34
 versionCode 1
 versionName "1.0"
 }
 
 // Other configurations...
}

app/src/main/AndroidManifest.xml:

xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.yourapp">

 <uses-sdk android:minSdkVersion="26" /> <!-- Ensure this matches your build.gradle -->
 
 <!-- Other manifest configurations... -->
</manifest>

After making these changes, clean and rebuild your project using Android Studio’s Build > Clean Project and Build > Rebuild Project menu options. The error should no longer appear because your app now explicitly targets Android versions that support the invoke-custom instructions used in your Kotlin code.

When to Use This Solution:

  • Your app targets modern Android devices (Android 8.0+)
  • You’re not concerned about supporting legacy devices
  • You want the simplest, most direct fix
  • Your project doesn’t have dependency conflicts with the new minimum SDK

Considerations:

  • This solution will prevent your app from installing on devices running Android versions below 8.0
  • You may need to update third-party dependencies to ensure compatibility with the new minimum SDK
  • Test thoroughly on your target devices to ensure functionality

This approach aligns with Android’s recommended practices for new applications, as Google encourages developers to target modern Android versions to take advantage of the latest features and security improvements.


Solution 2: Enabling Core Library Desugaring for Lower API Support

If your app needs to support Android versions older than API 26, you can enable core library desugaring in your Gradle configuration. This feature allows newer Java language features to work on older Android versions by processing them during the build process rather than relying on runtime support.

To enable core library desugaring, follow these steps:

Step 1: Update your app/build.gradle (Module: app):

gradle
android {
 // ... other configurations ...
 
 compileOptions {
 sourceCompatibility JavaVersion.VERSION_11
 targetCompatibility JavaVersion.VERSION_11
 }
 
 kotlinOptions {
 jvmTarget = "11"
 }
}

dependencies {
 // Add this dependency for core library desugaring
 coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
}

Step 2: Update your project-level build.gradle:

gradle
// Top-level build.gradle file

buildscript {
 // ... existing configurations ...
 
 dependencies {
 // Make sure you have the Android Gradle Plugin version compatible with your project
 classpath 'com.android.tools.build:gradle:8.1.4'
 
 // Other dependencies...
 }
}

Step 3: Verify your minimum SDK version remains appropriate for your target audience:

gradle
android {
 defaultConfig {
 minSdk 16 // Keep your original minimum SDK if supporting older devices
 targetSdk 34
 // ... other configurations ...
 }
}

After making these changes, clean and rebuild your project. The core library desugaring will process the invoke-custom instructions and convert them to compatible bytecode that works on your specified minimum SDK version.

Important Notes:

  • Core library desugaring adds approximately 1.5MB to your APK size
  • It may slightly increase build times due to the additional processing
  • Some advanced Java features may still not be fully supported on very old Android versions
  • Test thoroughly on your target devices to ensure compatibility

This solution is particularly valuable when:

  • Your app needs to support a broad range of Android devices
  • You’re working with legacy codebases that use modern Java features
  • You want to maintain compatibility with existing user bases on older devices
  • You’re gradually updating your minimum SDK version over time

The core library desugaring feature effectively bridges the gap between modern language features and older Android runtime environments, allowing you to use the latest Kotlin and Java capabilities while maintaining broad device compatibility.


Proper Kotlin Configuration for Updated Gradle Environment

After updating your Gradle build tools and resolving the invoke-customs error, it’s crucial to ensure your Kotlin configuration is properly aligned with your updated environment. This section covers the essential Kotlin settings that work well with the newer Gradle build tools and help prevent similar compatibility issues in the future.

Java Version Compatibility:
When working with modern Kotlin versions (1.8+), you should use Java 11 or higher for optimal compatibility. Configure this in your app/build.gradle file:

gradle
android {
 compileSdk 34
 
 kotlinOptions {
 jvmTarget = "11"
 }
 
 compileOptions {
 sourceCompatibility JavaVersion.VERSION_11
 targetCompatibility JavaVersion.VERSION_11
 }
}

Kotlin Android Extensions Plugin Update:
If you’re using the Kotlin Android Extensions plugin for view binding, note that it has been deprecated in favor of View Binding. Consider migrating:

gradle
plugins {
 id 'com.android.application'
 id 'org.jetbrains.kotlin.android'
 // Remove id 'kotlin-android-extensions' if present
}

android {
 // Enable View Binding instead
 buildFeatures {
 viewBinding true
 }
}

Kotlin Coroutines Configuration:
For modern Android development with Kotlin, ensure your coroutines are properly configured:

gradle
dependencies {
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}

Kotlin Serialization:
If you’re using Kotlin serialization, add the appropriate plugin and dependencies:

gradle
plugins {
 id 'com.android.application'
 id 'org.jetbrains.kotlin.android'
 id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.21'
}

dependencies {
 implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
}

Kotlin Multiplatform Considerations:
If planning for multiplatform development in the future, structure your project accordingly:

gradle
plugins {
 id 'com.android.application'
 id 'org.jetbrains.kotlin.multiplatform'
}

kotlin {
 android {
 compilations.all {
 kotlinOptions {
 jvmTarget = "11"
 }
 }
 }
 
 // Other target configurations...
}

Proguard/R8 Configuration for Kotlin:
Ensure your ProGuard/R8 configuration properly handles Kotlin classes:

gradle
android {
 buildTypes {
 release {
 minifyEnabled true
 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 
 // Add Kotlin-specific ProGuard rules
 proguardFiles 'proguard-rules-kotlin.pro'
 }
 }
}

Create a proguard-rules-kotlin.pro file with:

-keep class kotlin.Metadata { *; }
-keepclassmembers class * {
 @org.jetbrains.annotations.NotNull *;
 @org.jetbrains.annotations.Nullable *;
}

Testing Configuration:
Ensure your test configurations are compatible with your Kotlin setup:

gradle
dependencies {
 testImplementation 'junit:junit:4.13.2'
 testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3'
 androidTestImplementation 'androidx.test.ext:junit:1.1.5'
 androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}

By properly configuring these Kotlin-specific settings, you’ll create a more robust development environment that minimizes compatibility issues and takes full advantage of the features available in modern Android Studio with updated Gradle build tools.


Additional Configuration for Android Gradle Plugin 9.0+ Compatibility

When working with the latest Android Gradle Plugin versions (9.0+), you may need to make additional configuration adjustments to ensure full compatibility with your Kotlin codebase and avoid potential build issues. These configurations help maintain a smooth development experience as you continue updating your tooling.

AGP 9.0+ Configuration Changes:

Update your project-level build.gradle:

gradle
// Top-level build.gradle file

plugins {
 id 'com.android.application' version '8.1.4' apply false
 id 'com.android.library' version '8.1.4' apply false
 id 'org.jetbrains.kotlin.android' version '1.8.21' apply false
}

// Optional: Configure repositories in a centralized location
allprojects {
 repositories {
 google()
 mavenCentral()
 }
}

Namespace Configuration:
AGP 9.0+ requires explicit namespace configuration in your app-level build.gradle:

gradle
android {
 namespace 'com.yourapp'
 
 // ... other configurations ...
}

Build Features Configuration:
Explicitly declare your build features to avoid potential conflicts:

gradle
android {
 buildFeatures {
 viewBinding true
 dataBinding true // If using data binding
 compose true // If using Jetpack Compose
 }
 
 // Compose-specific configuration if using Jetpack Compose
 composeOptions {
 kotlinCompilerExtensionVersion '1.4.7'
 }
}

Kotlin Kapt Plugin Configuration:
If you’re using Kotlin annotation processing tool (KAPT), ensure proper plugin configuration:

gradle
plugins {
 id 'com.android.application'
 id 'org.jetbrains.kotlin.android'
 id 'org.jetbrains.kotlin.kapt' // Add KAPT plugin
}

dependencies {
 kapt 'androidx.room:room-compiler:2.5.2'
 kapt 'com.google.dagger:hilt-android-compiler:2.45.1'
}

R8 Configuration for Modern Android:
Update your R8 configuration for optimal performance with newer Android versions:

gradle
android {
 buildTypes {
 release {
 minifyEnabled true
 shrinkResources true
 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
 
 // Enable R8 full mode for better optimization
 crunchPngs false // Disable PNG crunching for better compression
 }
 }
}

Dependency Management for AGP 9.0+:
Be mindful of dependency conflicts that may arise with newer AGP versions:

gradle
dependencies {
 // Use consistent versions across dependencies
 implementation 'androidx.core:core-ktx:1.10.1'
 implementation 'androidx.appcompat:appcompat:1.6.1'
 implementation 'com.google.android.material:material:1.9.0'
 
 // Kotlin-specific dependencies
 implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1'
 implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1'
}

Gradle Properties Optimization:
Update your gradle.properties file for optimal performance with AGP 9.0+:

properties
# Gradle properties
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configureondemand=true

# Android-specific optimizations
android.useAndroidX=true
android.enableJetifier=true
android.nonTransitiveRClass=true
android.nonFinalResIds=true

Kotlin Multiplatform Configuration:
If planning for multiplatform development, configure it properly:

gradle
// In your app/build.gradle
kotlin {
 sourceSets {
 main {
 kotlin.srcDir("src/main/kotlin")
 resources.srcDir("src/main/res")
 }
 
 // Add other source sets as needed
 }
}

Version Catalogs (Recommended):
Consider using version catalogs for better dependency management:

gradle
// In gradle/libs.versions.toml
[versions]
agp = "8.1.4"
kotlin = "1.8.21"
coreKtx = "1.10.1"
appcompat = "1.6.1"
material = "1.9.0"

[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
android-library = { id = "com.android.library", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

// In your app/build.gradle, use the catalog
plugins {
 alias(libs.plugins.android.application)
 alias(libs.plugins.kotlin.android)
}

dependencies {
 implementation(libs.core.ktx)
 implementation(libs.appcompat)
 implementation(libs.material)
}

By implementing these additional configurations for Android Gradle Plugin 9.0+ compatibility, you’ll create a more robust and maintainable project structure that leverages the latest features while minimizing potential build issues. This forward-looking approach will help you stay current with Android development best practices as the tooling continues to evolve.


Sources

  1. Android Gradle Plugin Documentation — Official guide on invoke-customs error and minimum SDK requirements: https://developer.android.com/build/releases/gradle-plugin
  2. Kotlin Gradle Configuration Guide — Detailed instructions for configuring Kotlin projects with Java compatibility settings: https://kotlinlang.org/docs/gradle-configure-project.html

Conclusion

Resolving the “Invoke-customs are only supported starting with Android 0 --min-api 26” error after updating Gradle build tools requires understanding the relationship between your Kotlin code, Java compatibility settings, and Android API level requirements. Whether you choose to raise your minimum SDK version to 26+ or enable core library desugaring for broader device compatibility, the key is ensuring your build configuration aligns with the language features you’re using in your kotlin android studio project.

By properly configuring your android gradle plugin settings and following the solutions outlined above, you can maintain a smooth development workflow while leveraging modern Kotlin features. Remember to test thoroughly on your target devices after making these changes, and consider implementing the additional configurations for Android Gradle Plugin 9.0+ compatibility to future-proof your project against upcoming tooling updates.

Authors
Verified by moderation
Resolve Invoke-customs Error After Gradle Update