Upgrading Android Gradle Plugin from 3.5 to 4.1: Issues and Solutions
Upgrading a project from Android Gradle Plugin 3.5 to 4.1.3 required applying official migration steps, adjusting deprecated fields, resource paths, manifest tasks, ASM version, disabling configure‑on‑demand and the new zipflinger packager, and fixing NDK configuration, which together yielded roughly 36 % faster builds and a 5 MB smaller APK.
The upgrade was driven by new tool dependencies requiring Android Gradle Plugin (AGP) 4.1 or higher, while the project was still on AGP 3.5.0. To avoid blocking third‑party libraries that had not yet supported AGP 4.2, the team chose to upgrade to the highest 4.1.x release, AGP 4.1.3.
Adaptation followed the official release notes. AGP 3.6 changed native library packaging to uncompressed by default, increasing APK size; developers could revert to compressed packaging by adding android:extractNativeLibs="true" in the manifest. AGP 4.0 introduced dependency metadata stored in the APK signing block, which can be disabled via dependenciesInfo { includeInApk = false; includeInBundle = false } in build.gradle . AGP 4.1 removed the VERSION_NAME and VERSION_CODE fields from library module BuildConfig ; to obtain the app’s version, developers should use Context.getPackageName() combined with PackageManager .
Several issues appeared after applying the official changes. The BuildConfig.APPLICATION_ID field was deprecated and removed; the fix is to replace its usage with Context.getPackageName() . R and ProGuard mapping file paths changed starting with AGP 3.6 (e.g., R.txt moved from build/intermediates/symbols/ to build/intermediates/runtime_symbol_list/ ), requiring updates to backup scripts. Fixed resource ID handling broke in AGP 4.1 because the aaptOptions attribute disappeared from the resource task; the solution is to directly manipulate android.aaptOptions.additionalParameters . Manifest modification failed due to a new task process${variant.name.capitalize()}ManifestForPackage that runs after the original manifest process; writing extra information must target its output ( build/intermediates/packaged_manifests/ ). A Transform plugin using ASM failed because AGP upgraded the bundled ASM from version 6 to 7, exposing a bug in the Hunter library; removing Hunter and reimplementing the needed functionality resolved it. The error “Cannot change dependencies of dependency configuration” stemmed from having org.gradle.configureondemand enabled; disabling it fixed the problem. Entry name collisions arose from the new zipflinger packager introduced in AGP 3.6 and made default for release builds in AGP 4.1; either disable it via android.useNewApkCreator=false in gradle.properties or eliminate duplicate entries in dependent JARs/AARs. Finally, SO files were not stripped because the NDK path could not be located; configuring android.ndkVersion (or android.ndkPath ) to match the machine’s NDK installation restored stripping.
After the upgrade, build speed improved by approximately 36% and the APK size decreased by about 5 MB.
The documented problems and solutions should help other developers perform a similar AGP upgrade smoothly and benefit from the ongoing optimizations in the Android build tools.
NetEase Cloud Music Tech Team
Official account of NetEase Cloud Music Tech Team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.