Search code examples
androidgradleandroid-gradle-plugin

AGP 8.4+ and Hilt (Android Library Modules in Multi-module architecture, R8)


I found this patch note when the 8.4 version came out: https://developer.android.com/build/releases/past-releases/agp-8-4-0-release-notes#library-classes-shrunk

"Starting with Android Gradle Plugin 8.4, if an Android library project is minified, shrunk program classes will be published for inter-project publishing. This means that if an app depends on the shrunk version of the Android library subprojects, the APK will include shrunk Android library classes. You may need to adjust library keep rules in case there are missing classes in the APK. In case you are building and publishing an AAR, local jars that your library depends on will be included unshrunk in the AAR, which means code shrinker won't run on them. To revert to previous behavior, set android.disableMinifyLocalDependenciesForLibraries in the gradle.properties file and file a bug. Future versions of AGP will remove this flag remove this flag."

This is a little bit cryptic to me.

Can someone explain it to me?

Let's imagine I have a multi module app with the following dependency:

  • app module

  • presentation module (Android module)

  • domain module (Kotlin module)

  • data module (Android module)

The dependency graph

presentation -> domain <- data

And app has dependency in all modules.

And app uses classes from the presentation module.

So the way it goes that if my Library modules has isMinifyEnabled = true then they will get minified BEFORE the app module does and the app module will include these minified ones?

So if I set the isMinifyEnabled = false in my Library modules but keep the isMinifyEnabled = true in my app module, does this mean they (the Library modules) still get minified and obfuscated? Or I have to add the rules and the @keep annnotation into almost everything I use inside the app module from library module?

And If I just mark everything with @keep would obfuscation not lose its meaning?


Solution

  • I can't answer all your questions in detail, but I will try to provide a solution for updating Gradle to version 8.4+.

    if my Library modules has isMinifyEnabled = true then they will get minified BEFORE the app module does and the app module will include these minified ones?

    It seems that, if you run the gradlew app:assembleRelease command, the minifyReleaseWithR8 task will be run on all modules that are configured with the isMinifyEnabled property set to true, before the app module itself.

    if I set the isMinifyEnabled = false in my Library modules but keep the isMinifyEnabled = true in my app module, does this mean they (the Library modules) still get minified and obfuscated?

    Yes, you can check this by running gradlew app:assembleRelease. After that, just drop the compiled APK file into Android Studio (or use JADX). However, now minifyReleaseWithR8 (mentioned above) will not be executed on any of your other modules except the app module.

    I have to add the rules and the @keep annnotation into almost everything I use inside the app module from library module?

    If I understand your question correctly, you don't need to move all your module's rules to the app's proguard-rules file.

    To solve the missed classes in the release builds, I reconfigured my build.gradle files for the library modules as follows:

    android {   
    
        // be sure, that you provide the `consumeProguardFiles`
        defaultConfig {
          consumerProguardFiles 'consumer-rules.pro'
        }
    
        // remove minifyEnabled = true, or completly buildTypes block if have only release without additional configuration.
        // buildTypes {
        //    release {
        //        minifyEnabled true
        //        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        //    }
        // }
    }