Use Proguard for stripping unused Support lib classes - android

I'm adding the Android Support library to my project and I've noticed the resulting APK file inflates in size quite a bit.
What I'm trying to do is use Proguard to remove classes in the library that I don't use, e.g. the backword compatible Notification builder class (in fact, I tested this without even using anything from the Support lib, I just dropped it in my /libs folder).
My proguard.cfg is exactly what's in <sdktools>\tools\proguard\proguard-android.txt, with my own addition of -dontobfuscate (as I don't really need obfuscation), however, I'm not seeing my .APK file become any smaller. My proguard.cfg is below:
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
-dontobfuscate
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native ;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# 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);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static ;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**

The Android SDK only applies ProGuard in release builds, not in debug builds.
Furthermore, the Android SDK (r20 or higher) typically looks for proguard-project.txt instead of proguard.txt in your project. This file can generally be empty, because the build process also reads the global file proguard-android.txt. You may want to update your project with
android update project -p MyProjectDirectory
Finally, the Android SDK (r20 or higher) disables ProGuard's optimization step by default (which can improve on its shrinking step). You can enable it by pointing to proguard-android-optimize.txt instead of proguard-android.txt in your project.properties.

Related

Android ProGuard obfuscation of library: keep class not working

Intro: I have in AS 1 project with 2 models:
Android library project with some "Public API class"
Android APP dependent on above library (the library module is on the dependency list)
Task: I want to obfuscate my library project because I want to expose it as public SDK but keep my code protected...
What I did: So I made custom ProGuard rules:
-dontshrink
-dontoptimize
-dontpreverify
-keep class com.org.my_public_api_class_name
I skip all other stages in order to eliminate where the bug is to only obfuscation stage.
Result: Build of the APP module fails with errors like
Error: cannot find symbol class my_public_api_class_name
It seems for me that the problem is that the obfuscation NOT skipped the class I wanted to, so now he has some meaningless name and therefore in the APP, where I'm using him, The original name not exist.
Thanks,
To exclude your class from obfuscation, try this:
-keep class com.org.my_public_api_class_name**
-keepclassmembers class com.org.my_public_api_class_name** {*;}

Proguard returned with error code 1. See console java.io.IOException

While exporting my Android Application from Eclipse IDE, I am getting errors as below:
Proguard returned with error code 1. See console
Warning: library class android.net.http.AndroidHttpClient extends or implements program class org.apache.http.client.HttpClient
You should check if you need to specify additional program jars.
Warning: there were 1 instances of library classes depending on program classes.
You must avoid such dependencies, since the program classes will
be processed, while the library classes will remain unchanged.
java.io.IOException: Please correct the above warnings first.
at proguard.Initializer.execute(Initializer.java:321)
at proguard.ProGuard.initialize(ProGuard.java:211)
at proguard.ProGuard.execute(ProGuard.java:86)
at proguard.ProGuard.main(ProGuard.java:492)
project.properties
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt:proguard-google-api-client.txt
# Project target.
target=android-21
proguard-project
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-dontwarn com.google.android.gms.**
-dontwarn javax.jdo.**
-dontwarn com.google.api.client.googleapis.extensions.android.gms.**
-dontwarn org.apache.commons.**
-dontwarn org.ietf.jgss.**
-dontnote
I have added dontwarn and dontnote statements to proguard confing file with that I resolved few warnings but Not able to solve remaining issue.Please help me to solve this.Thanks you.
You Just need to add below code to your project's proguard-project.txt file.
-dontwarn ["error package name or Error file path here"]
example as :
-dontwarn com.example.media.*
and if you have more(insane) errors coming, then just add
-dontskipnonpubliclibraryclassmembers
May be this helpful for you.
Add this to Your proguard-project file:
-keep class org.apache.http.** { *; }
-dontwarn org.apache.http.*
Then come back if still errors exists.
please used comments before the given code bellow
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt:proguard-google-api-client.txt
In project.properties file
I also have faced this problem. Cleaning the project and exporting again should fix this.
As the issue was due to library class android.net.http.AndroidHttpClient and org.apache.http.client.HttpClient, I added -dontwarn statements for both the library classes to proguard-project file. what I added is:
-keep class org.apache.http.** { *; }
-dontwarn org.apache.http.*
-dontwarn android.net.http.*
and I am done. Thank you all for helping out on this.

Is there an example for getting Proguard working with Cocos2d-x? And twitter4j

I've searched discuss.cocos for an example but there isn't one. Feeling this to be a more OS agnostic platform to ask on I search for enlightenment here.
I got a massive headache after turning it on by writing
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt
in project.properties in my project's base directory.
I couldn't copy-past text because the console display in Eclipse immediately cleared and presented like there was nothing wrong but I got "error code 1. See console" type of message, repeatedly.
Though the problem appears to be with twitter4j I'm sure there are many more warnings that scrolled by before that, well, I'm not sure, the whole thing was so sudden.
I've trawled this site for help and while most advice consists of adding dontwarn lines I feel I need to be exporting libraries instead of, as I did with twitter4j, just copying the libjar to my project's own lib folder.
I've tried adding:
-dontwarn twitter4j.management.**
-dontwarn twitter4j.**
-dontwarn javax.management.**
-dontwarn com.google.api.client.googleapis.extensions.android.gms.**
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
-keep class java.lang.management.** { *; }
-keep class com.google.code.** { *; }
-keep class oauth.signpost.** { *; }
-libraryjars /libs/twitter4j-core-3.0.3.jar
-keep class twitter4j.**
-keepclassmembers class twitter4j.** {
<init>(...);
<methods>;
<fields>;
}
To proguard-project.txt but it had no effect. I'm tending not to want to bother with proguard since C++ is much better for obfuscation anyway. It's strange how none of the howto's I read promoted including the entire twitter4j project. I prefer the small 300kb library. But not if it's limiting optimisations in other respects.
My SDK is version 22.6 by the way.
____EDIT____
In looking for a complete example i found SDK/tools/proguard/examples/android.pro
I tried copy pasting the lot to no further effect but was disconcerted by the advice in the header of that file:
If you're using the Android SDK (version 2.3 or higher), the android tool
already creates a file like this in your project, called proguard.cfg.
It should contain the settings of this file, minus the input and output paths
(-injars, -outjars, -libraryjars, -printmapping, and -printseeds).
The generated Ant build file automatically sets these paths.
Android tool? proguard.cfg? Surely proguard knows the new files are merely instructed to reference the configs in the SDK/tools/proguard directory?
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt
You say you're changing proguard-project.txt, but are you actually using that file? Have you changed project.properties to point to your file instead of the default android one?
proguard.config=proguard-project.txt
Your project.properties file should point to Android's default configuration and to your own project-specific configuration:
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
This is the standard line in the properties files that the Android SDK generates.
In your proguard-project.txt file, you can then add -keep options to avoid problems with code that performs reflection. In this case, you should also add -dontwarn options to reassure ProGuard that the missing dependencies are not a problem in practice. It will then proceed processing the application.
You should not add -libraryjars options, since the Android build process already automatically specifies all necessary -injars, -outjars, and -libraryjars for you.

Exception while trying to configure proguard for obfuscation . Duplicate class definitions

I am trying to obfuscate my code using proguard . I am using google maps in my project .
But i am getting the following exceptions .
How to resolve ?
Proguard returned with error code 1. See console
Warning: class [bin/classes/com/google/android/gms/BuildConfig.class] unexpectedly contains class [com.google.android.gms.BuildConfig]
Warning: class [bin/classes/com/google/android/gms/R$attr.class] unexpectedly contains class [com.google.android.gms.R$attr]
Warning: class [bin/classes/com/google/android/gms/R$id.class] unexpectedly contains class [com.google.android.gms.R$id]
Warning: class [bin/classes/com/google/android/gms/R$string.class] unexpectedly contains class [com.google.android.gms.R$string]
Warning: class [bin/classes/com/google/android/gms/R$styleable.class] unexpectedly contains class [com.google.android.gms.R$styleable]
Warning: class [bin/classes/com/google/android/gms/R.class] unexpectedly contains class [com.google.android.gms.R]
Note: there were 1656 duplicate class definitions.
Warning: there were 6 classes in incorrectly named files.
You should make sure all file names correspond to their class names.
The directory hierarchies must correspond to the package hierarchies.
If you don't mind the mentioned classes not being written out,
you could try your luck using the '-ignorewarnings' option.
java.io.IOException: Please correct the above warnings first.
at proguard.InputReader.execute(InputReader.java:133)
at proguard.ProGuard.readInput(ProGuard.java:196)
at proguard.ProGuard.execute(ProGuard.java:78)
at proguard.ProGuard.main(ProGuard.java:492)
Proguard returned with error code 1. See console
proguard.ParseException: Unexpected keyword 'names' in line 30 of file 'D:\redBus_Update_3\proguard-project.txt',
included from argument number 4
at proguard.ConfigurationParser.unknownAccessFlag(ConfigurationParser.java:1048)
at proguard.ConfigurationParser.parseClassSpecificationArguments(ConfigurationParser.java:547)
at proguard.ConfigurationParser.parseKeepClassSpecificationArguments(ConfigurationParser.java:490)
at proguard.ConfigurationParser.parse(ConfigurationParser.java:138)
at proguard.ProGuard.main(ProGuard.java:484)
Please find the contents of the proguard file below .
I tried using ignore warnings options for those files as well
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-libraryjars D:\google-play-services_lib_en
-libraryjars D:\redBus_Update_3\libs\FlurryAgent.jar
-libraryjars D:\redBus_Update_3\libs\gson-2.2.2.jar
-libraryjars D:\redBus_Update_3\libs\bugsense-3.0.1.jar
-libraryjars D:\redBus_Update_3\libs\android-support-v4.jar
-keep class android.location.** { *; }
-keep public class com.google.android.maps.** {*;}
-keep public class com.google.android.maps.** {*;}
-keep public class com.google.android.gms.maps.** {*;}
-dontwarn com.google.android.maps.GeoPoint
-dontwarn com.google.android.maps.MapActivity
-dontwarn com.google.android.maps.MapView
-dontwarn com.google.android.maps.MapController
-dontwarn com.google.android.maps.Overlay
You shouldn't specify any -libraryjars options in your proguard-project.txt. The standard build script automatically passes the libraries that it can find in the libs directory to ProGuard.
If you get any warnings about missing classes, even though the application works fine in debug mode, you should consider adding -dontwarn options for these classes (cfr. many related questions and answers on this site).
I had this issue recently. My solution to it end up being that I just needed to clean the project, which lead me to a different error:
/gen already exists but is not a source folder. Convert to a source folder or rename it.
So I renamed it genX, which was then auto recreated, cleaned the project, tested it, then deleted genX.
Doing this solved my Proguard issues.

How to exclude R*.class files from a proguard build

I am one step away from making the method described here:
Targeting Android with Scala 2.8 Trunk builds
work with a single project (vs one project for scala and one for android).
I've come across a problem. Using this input file (arguments to) proguard:
-injars bin;lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)
-outjar lib/scandroid.jar
-libraryjars lib/android.jar
-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class org.scala.jeb.** { public protected *; }
-keep public class org.xml.sax.EntityResolver { public protected *; }
Proguard successfully builds scandroid.jar, however it appears to have included the generated R classes that the android resource builder generates and compiles. In this case, they are located in bin/org/jeb/R*.class. This is not what I want. The android dalvik converter cannot build because it thinks there is a duplicate of the R class (it's in scandroid and also the R*.class files). How can I modify the above proguard arguments to exclude the R*.class files from the scandroid.jar so the dalvik converter is happy?
Edit: I should note that I tried adding ;bin/org/jeb/R.class;etc... to the -libraryjars argument, and that only seemed to cause it to complain about duplicate classes, and in addition proguard decided to exclude my scala class files too.
I use this option. You can find reference from link below and find "A complete Android application".
http://proguard.sourceforge.net/index.html#/manual/examples.html
-keepclassmembers class **.R$* {
public static <fields>;
}
file filter !**/*R.java in other words this lien forces Proguard to keep all java files except R.java files in the obfuscation

Categories

Resources