# Increased accuracy of aapt2 "keep" rules

DevFeed: [Increased accuracy of aapt2 "keep" rules](<https://devfeed.tech/articles/increased-accuracy-of-aapt2-keep-rules-20939.md>)

Original publisher: [Read original article](<https://jakewharton.com/increased-accuracy-of-aapt2-keep-rules/>)

Published: 2018-08-07T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Android Studio](<https://devfeed.tech/topics/android-studio.md>), [R8](<https://devfeed.tech/topics/r8.md>), [APK](<https://devfeed.tech/topics/apk.md>), [XML](<https://devfeed.tech/topics/xml.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [android-gradle-plugin](<https://devfeed.tech/tags/android-gradle-plugin.md>), [apk](<https://devfeed.tech/tags/apk.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>)

## AI overview

This article explains how Android Gradle Plugin 3.3.0-alpha05 made aapt2 generate more precise keep rules for constructors referenced through Android resource XML and manifests. The change prevents unused constructors from being retained in release APKs, reducing method counts and enabling more optimization by R8.

## Source excerpt

The aapt2 tool packages your Android application resources into the format used at runtime. It also generates "keep" rules for ProGuard or R8 so that the types referenced inside of your resources do not get removed. Views referenced only in layout XML, action providers referenced only in menu XML, and broadcast receivers referenced only in the manifest XML are some examples of types that would otherwise be removed from the final APK were it not for these rules. Prior to version 3.3.0-alpha05 of the Android Gradle plugin, aapt2 would generate "keep" rules for the constructors of these types using an argument wildcard. Some rules for an application class, activity class, and view reference look like this: # Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:20 -keep class com.jakewharton.sdksearch.SdkSearchApplication { <init>(...); } # Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:28 -keep class com.jakewharton.sdksearch.ui.MainActivity { <init>(...); } # Referenced at search/ui-android/build/intermediates/packaged_res/release/layout/search.xml:57 -keep class android.support.v7.widget.RecyclerView { <init>(...); } Dumping the methods of the release APK we get: com.jakewharton.sdksearch.SdkSearchApplication <init>() com.jakewharton.sdksearch.ui.MainActivity <init>() android.support.v7.widget.RecyclerView <init>(Context) android.support.v7.widget.RecyclerView <init>(Context, AttributeSet) android.support.v7.widget.RecyclerView <init>(Context, AttributeSet, int) SdkSearchApplication and MainActivity contain only a default constructor but RecyclerView contains three. As far as the reflective lookup is concerned, only one constructor will be used. For types in the manifest the default (no-argument) constructor is used. For types in a layout XML file the two-arg Context+AttributeSet constructor is invoked by LayoutInflater. By generating rules with <init>(...) we are forcing ever