I have applied ProGuard to my Android application.
I'm using
android-studio/sdk/tools/proguard/proguard-android.txt
as a configuration file, changing nothing.
In this file I can see the only statement regarding Activity:
We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
It follows from that the Activities class names are obfusctated by ProGuard while some methods are preserved as they are. This is understandable.
However, in my application I then create an Activity Class from a string using
Class.forName("my.app.MyActivity")
then I start this Activity and it starts fine.
But that means Activity-derived classes are not obfuscated??. It should have failed because ProGuard does not have -keep class
directive for Activity
, it only has -keepclassmembers.
Can someone, please, explain, if I can rely on the behaviour I observe? Or do I misunderstand the -keepclassmembers
directive?
From the ProGuard FAQ:
Does ProGuard handle Class.forName calls?
Yes. ProGuard automatically handles constructs like Class.forName("SomeClass") and SomeClass.class. The referenced classes are preserved in the shrinking phase, and the string arguments are properly replaced in the obfuscation phase. With variable string arguments, it's generally not possible to determine their possible values. They might be read from a configuration file, for instance. However, ProGuard will note a number of constructs like "(SomeClass)Class.forName(variable).newInstance()". These might be an indication that the class or interface SomeClass and/or its implementations may need to be preserved. The developer can adapt his configuration accordingly.
So, ProGuard's being cleverer than you expected: it will automatically detect and handle simple cases of the use for forName()
. Even if the class isn't referenced in the Android manifest file, ProGuard will obfuscate the class name in both the class and in your call to forName()
.
For Activities, it wouldn't surprise me if you're doubly-covered by both this behaviour and by the Android-specific input to ProGuard that's part of the build process, as @laalto mentions in his answer.
Because the activities are listed in the manifest and classes referenced there are automagically kept. This is needed because the Android framework accesses these app entry points via reflection.
From here:
The build process runs the tool aapt to automatically create the configuration file
bin/proguard.txt
, based onAndroidManifest.xml
and other xml files. The build process then passes the configuration file to ProGuard. So ProGuard itself indeed doesn't considerAndroidManifest.xml
, but aapt+ProGuard do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With