Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell ProGuard to keep everything in a particular package?

My application has many activities and uses native library too. With the default ProGuard configuration which Eclipse generates ProGuard removes many things - OnClick methods, static members, callback methods which my native library uses... Is it there a simple way to instruct ProGuard to NOT remove anything from my package? Removing things saves only about 2.5% of the application size, but breaks my application completely. Configuring, testing and maintaining it class by class in ProGuard configuration would be a pain.

like image 279
ggurov Avatar asked Sep 18 '11 19:09

ggurov


People also ask

How do you keep all classes in ProGuard?

-keepclassmembernames. This is the most permissive keep directive; it lets ProGuard do almost all of its work. Unused classes are removed, the remaining classes are renamed, unused members of those classes are removed, but then the remaining members keep their original names.

Does ProGuard obfuscate package name?

Obfuscating package names myapplication. MyMain is the main application class that is kept by the configuration. All other class names can be obfuscated. Note that not all levels of obfuscation of package names may be acceptable for all code.

How do you set ProGuard rules?

When you create a new project or module using Android Studio, the IDE creates a <module-dir>/proguard-rules.pro file for you to include your own rules. You can also include additional rules from other files by adding them to the proguardFiles property in your module's build.


2 Answers

EDIT This answer is 10 years old - it may not apply to newer proguard versions.

I think you need to add these flags at the very least (modify for you individual package names):

-keep class javax.** { *; } -keep class org.** { *; } -keep class twitter4j.** { *; } 

Also, add these flags:

-dontshrink -dontoptimize -dontpreverify 

Here's my whole config file: of my Proguard.cfg:

-dontshrink -dontoptimize -dontpreverify -verbose  -dontwarn javax.management.** -dontwarn java.lang.management.** -dontwarn org.apache.log4j.** -dontwarn org.apache.commons.logging.** -dontwarn org.slf4j.** -dontwarn org.json.**   -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 -keep class javax.** { *; } -keep class org.** { *; } -keep class twitter4j.** { *; }  -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 *; } 
like image 142
Caspar Harmer Avatar answered Sep 19 '22 09:09

Caspar Harmer


As final result I found that just keeping all class members is not enough for the correct work of my application, nor necessary. I addded to the settings file this:

-keepclasseswithmembers class * {     void onClick*(...); } -keepclasseswithmembers class * {     *** *Callback(...); } 

The case with onClick* is for all methods which I address in android:onClick atribute in .xml layout files (I begin the names of all such methods with 'onClick').

The case with *Callback is for all callback methods which I call from my native code (through JNI). I place a suffix 'Callback' to the name of every such method.

Also I added few rows for some special cases with variables which I use from native code, like:

-keep class com.myapp.mypackage.SomeMyClass {     *** position; } 

(for a varible with name 'position' in a class with name 'SomeMyClass' from package com.myapp.mypackage)

All this is because these onClick, callback etc. must not only be present but also kept with their original names. The other things ProGuard can optimize freely.

The case with the native methods is important also, but for it there was a declaration in the generated from Eclipse file:

-keepclasseswithmembernames class * {     native <methods>; } 
like image 45
ggurov Avatar answered Sep 20 '22 09:09

ggurov