Why proguard don´t know automatically which files should be kept - android

Why android studio can´t infer which classes do we need so the other´s can be removed using shrink?
Why do we need to write manually which classes should be kept?

ProGuard is a general-purpose Java development tool. It knows nothing about classes that might be referred to from the Android manifest, layout resources, menu resources, preference XML, and so on.
More generally, ProGuard has no way of reliably determining what classes are loaded via reflection, which is how all of the above is implemented. For those classes, you need to teach ProGuard to keep them.

Also the "update project" command from /ANDROID_SDK/tools/android will generate a proguard with common classes that should be kept.
The default is enough for most applications.
You should add Innerclasses that are used as listener of JavaScript on WebViews.
And the cases you find that you will need names (reflections or anything else)
The default proguard.cfg looks like this:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

Related

How to use Proguard with Android Annotations?

Does anybody know how to use Proguard with Android Annotations?
I found this resource:
https://code.google.com/p/androidannotations/wiki/ProGuard
But when I use the proguard.cfg file from there, I get the following error:
proguard.ParseException: Unknown option '*' in line 6 of file
'/Users/jabdulius/Documents/Dropbox/workspace-tinder/Tinder/proguard.cfg'
Here's the proguard.cfg file I copied from the link:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/ *,!class/merging/ *
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
When you copy and paste from the website, you may notice your paste includes spaces before the asterisks that were not present in the original (a minor formatting error).. simply remove the two spaces, changing the following line:
-optimizations !code/simplification/arithmetic,!field/ *,!class/merging/ *
to match this:
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
You'll also note, as Eric has said (and he would know best!!) the newer versions of ADT include a default proguard configuration referenced in new project.properties:
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
Uncommenting the line (remove the #)will load the default properties (proguard-android.txt) and then override it with any changes you make in your project proguard-project.txt.
Those default properties include many of the rules that Android Annotations project recommends, and are sufficient for most basic apps.
As of Android SDK r20, the ProGuard configuration file is called proguard-project.txt, and it can be empty to start with. It only needs to contain project-specific settings. Try upgrading your SDK and your project.

Android: proguard is not obfuscating the source

I have enabled proguard in project.properties:
proguard.config=proguard.cfg
My proguard.cfg does not disable obfuscation. But nothing is obfuscated.
I run the project build with
ant release.
Any bells ringing?
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/,!class/merging/
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native ; }
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet); }
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet, int); }
-keepclassmembers class * extends android.app.Activity { public void *(android.view.View); }
-keepclassmembers enum * {
public static *[] values();
public static * valueOf(java.lang.String); }
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
You should make sure that your project is configured for your Android SDK:
android update project -p MyProjectDirectory
As of Android SDK r20, the ProGuard configuration file is split into several parts, which are specified in project.properties:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
The short project-specific configuration is defined in proguard-project.txt (no longer in proguard.cfg, like it was in older versions of the SDK). The SDK documentation may not be entirely up to date in this respect.
When you run ant release, you should see some logging output from ProGuard.
#Thanks Danail, Today i just overcome from this problem .Just elaborating
android:debuggable
Whether or not the application can be debugged, even when running on a device in user mode — "true" if it can be, and "false" if not. The default value is "false".
For more details you can visit
http://www.vogella.com/tutorials/AndroidDebugging/article.html
It was way more trivial than what I thought: we had (in our manifest.xml file) enabled the
android:debuggable="true"
Doh.

android:onClick not working with ProGuard

Since today, something weird is happening with my application. Every time I click a button that has set the android:onClick attribute, I get an IllegalStateException: Could not find a method ...
I noticed that only happens when I enable Proguard in the file: default.properties
This is my proguard.cfg:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
The thing is that doesn't happened last week.. (I was using proguard too). Any ideas?
EDIT
I found another solution to this problem:
The project with problems was created with an old version of the ADT plugin (Eclipse). I created a new project with the same parameters and copied the src/, res/ and Manifest, and problem solved!
in the example file in the android framework tools (YOUR_ANDROID_DIR/tools/proguard/proguard-android.txt), you can find the following rule:
# 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);
}
With the comment it's quite explicit.
You need to tell proguard not to mutate the method associated with your android:onClick tag.
Here is an example rule (taken from the proguard website):
-keep class mypackage.MyCallbackClass {
void myCallbackMethod(java.lang.String);
}

What do I need to put in proguard.cfg to enable obfuscation?

I have the following code in my application's proguard.cfg (and yes, I also have proguard.config=proguard.cfg in build.properties):
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
Yet, I was surprised to see an error report from the Android Market containing Unobfuscated symbols in the stack trace.
I know I uploaded an ProGuard exported version, so what did I miss?
If your stack trace included unobfuscated class names and methods specified in the --keep statements in your proguard.cfg, then the answer is in the body of your question...
Also note that due to the challenges posed by reflection, ProGuard automatically keeps the following:
Class.forName("SomeClass")
SomeClass.class
SomeClass.class.getField("someField")
SomeClass.class.getDeclaredField("someField")
SomeClass.class.getMethod("someMethod", new Class[] {})
SomeClass.class.getMethod("someMethod", new Class[] { A.class })
SomeClass.class.getMethod("someMethod", new Class[] { A.class, B.class })
SomeClass.class.getDeclaredMethod("someMethod", new Class[] {})
SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class })
SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class, B.class })
AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")
AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")
AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")
Also note that if you somehow provide the file proguard/mapping.txt generated by ProGuard, the tool ReTrace can un-obfuscate everything.
In short, you don't need to put anything in proguard.cfg to enable obfuscation. The default options are sufficient. Theoretically, you may want to remove some of the default --keep options but ProGuard's documentation specifically states that:
For proper results, you should at least be somewhat familiar with the
code that you are processing. Obfuscating code that performs a lot of
reflection may require trial and error, especially without the
necessary information about the internals of the code.

Error in default proguard.cfg?

When I create a new Android project in Eclipse, the following default proguard.cfg file is created:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
Note that the -optimizations line comments out the rest of the file. I'm wondering if it is intentional or if it is a typo and that line should have its last two characters reversed:
-optimizations !code/simplification/arithmetic,!field/*,!class/merging*/
I'm using ADT plugin 9.0 and Eclipse 3.6.1.
Okay. I'm now feeling a little stupid. The answer is that nothing here is a comment. The line should be interpreted as if it were spaced out like this:
-optimizations !code/simplification/arithmetic,
!field/*,
!class/merging/*
The * is a wildcard character and the syntax highlighting done by the forum is wrong in this case.
Are you sure you didn't accidently do that?
I just created a dummy project and ended up with this. I'd try to remove that line and see if that works.
-injars bin/classes
-injars libs
-outjars bin/classes-processed.jar
-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
The keep-statements are used to prevent proguard from removing classes or class members in the shrinking step and from renaming them in the obfuscation step.
An Activity is a class that you most likely don't want to be romoved from your project. On Android's ProGuard page it says
For some situations, the default configurations in the proguard.cfg file will suffice. However, many situations are hard for ProGuard to analyze correctly and it might remove code that it thinks is not used, but your application actually needs. Some examples include:
List item a class that is referenced only in the AndroidManifest.xml file
Since that keep part is commented out in the default config I think it is intented, because the out commented -keep Activities line would prevent proguard from eliminating any activity.
In short: No typo

Categories

Resources