A common pattern in ProGuard configs for Android applications is to preserve custom View
classes, since they are probably referenced only from layout XML instead of application code.
Upon project creation, the ADT therefore add these rules to a project's proguard.cfg:
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
I guess the idea here is to say that whenever a class defines a constructor that may be called by a layout inflater, then preserve it. However, according to the ProGuard docs, the keepclasseswithmembernames
qualifier is shorthand for keepclasseswithmembers
and allowshrinking
, which if I understand correctly means: it's allowed to remove these classes, but if they're kept, don't obfuscate its member names (probably to not break bindings between XML attribute names and class setters).
But doesn't that mean that those classes will still be removed during the shrinking phase (allowshrinking = true), unless they are referenced directly in code? Indeed that is what happened with a custom widget we're using in our app, and I could fix the issue by setting the rule to just keepclasseswithmembers
since that will simply preserve the matching classes entirely (it's worth noting that this is what the official ProGuard Android example does, too).
Am I misreading the ProGuard docs or is this a bug in the ADT project wizard?
The configuration in the Android SDK (at least up to version 11) is not entirely correct, indeed.
The configuration for Android in the ProGuard documentation correctly specifies "-keepclasseswithmembers", not "-keepclasseswithmembernames".