I am using Xamarin.Forms. I have Android app of size 35MB after applying ProGuard it only reduce nearly 1MB of size. I have checked ProGuard option in Property window and added custom proguard.cfg file in my android project level to remove warnings.
Linker using 'SDK and User assemblies'.
proguard.cfg file
-dontwarn com.symbol.emdk.**
-dontwarn com.symbol.emdk.scanandpair.**
-dontwarn com.symbol.emdk.simulscan.**
-dontwarn com.symbol.emdk.barcode.**
-dontwarn org.apache.http.**
-dontwarn com.appdynamics.eumagent.runtime.**
-keep class android.support.v7.widget.FitWindowsLinearLayout { *; }
Is there any way to reduce APK size more using ProGuard only?
If you develop a Xamarin application there is not much use in using ProGuard as most of the code will be compiled as native code and included as dll in the final apk.
ProGuard processes only JVM class files (there are different languages that produce class files, e.g. java, kotlin, groovy, ...).
These 4 things reduce your apk size almost 50-60%
Replace proguard-android.txt with proguard-android-optimize.txt.
Make minifyEnabled true
Add shrinkResources true
Add resConfigs
ex:-
buildTypes {
release {
minifyEnabled true
shrinkResources true
resConfigs "en"
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Details:
proguard-android-optimize.txt is the more aggressive progurard configuration than proguard-android.txt.
shrinkResources attribute will remove all the resources, those are not used anywhere in the project.
resConfigs attribute will remove all the other localized resources while building the application. Here, it strips other than english resources.
Related
When I upgraded to the latest Gradle version, my class names are not being obfuscated anymore. The current studio version is 3.4.2
As the latest version uses R8 obfuscation instead of Proguard, I have removed the previous configuration of proguard-rules.pro as it does almost nothing at all.
I still use
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
and inside proguard-rules.pro i left only this:
-allowaccessmodification
-repackageclasses
The result is somehow obfuscated java code inside classes, but preserved class names and when apply some reverse engineering all original class names are visible. Need some help with this R8 to make it work as desired. Thank you in advance!
From this reference:
https://github.com/codepath/android_guides/wiki/Building-your-own-Android-library
I have the following gradle file:
android {
compileSdkVersion 25
buildToolsVersion "26.0.2"
buildTypes {
release {
minifyEnabled true
consumerProguardFiles 'consumer-proguard-rules.pro'
}
}
}
And the following proguard file:
-dontobfuscate
-optimizations !code/allocation/variable
-keep public class * {
public protected *;
}
However all of my classes in the aar are missing when I run the 'assembleRelease' task to build my release aar file.
Any ideas?
You should set minifyEnabled to false (the default value) :
consumerProguardFiles is not used for immediate minification (i.e. when building the library itself). It it used when the consumer of the library (e.g. an application) is build.
Minifying the library before consumption is not recommended, because you can not know what parts will actually be used before the final build. Libraries usually don't do it. e.g. LeakCanary, ACRA, Butter Knife
in general, a library must keep the all the methods and method names, required to operate it; eg:
-verbose
# -libraryjars ../app/libs
# -dontpreverify
# -dontobfuscate
# -dontshrink
# -dontoptimize
# keep class BuildConfig
-keep public class **.BuildConfig { *; }
# keep class members of R
-keepclassmembers class **.R$* {public static <fields>;}
the answer to the question should probably be:
# keep all public and protected method names,
# which could be used by Java reflection.
-keepclassmembernames class * {
public protected <methods>;
}
there are most likely some more rules required, while the -verbose flag tells one what to write into there. when building the library against other code (as suggested above), one nevertheless needs to add more or less the same rules for the library. there are also quite some, not open source, libraries with obfuscated class names.
a library's build.gradle might look about like this:
android {
defaultConfig {
consumerProguardFiles 'proguard-consumer-rules.pro'
}
buildTypes {
release {
minifyEnabled false // don't proguard the library itself.
}
}
}
the default proguard-consumer-rules.pro explains it:
The Android Gradle plugin allows to define ProGuard rules which get embedded in the AAR.
These ProGuard rules are automatically applied when a consumer app sets minifyEnabled to true.
The custom rule file must be defined using the 'consumerProguardFiles' property in your build.gradle file.
When a library is not being processed itself, it still can bring it's ProGuard rules - in order to be consumed, when building the whole project.
I am not getting what you actually want to do, but I can suggest you one thing that is just don't do assembleRelease instead import in your another project, clean project and build then use the generated aar from the /build/outputs/aar/ directory. And must check you are not using reference of obfuscated class anywhere.
I upgraded to Android Studio 2.0 Beta 5. I'm using gradle tools 2.0.0-beta5. On the Android dev blogspot site, there is a video explaining how to use the new Shrinker for debug builds (at 3:14)
https://www.youtube.com/watch?list=PLWz5rJ2EKKc_w6fodMGrA1_tsI3pqPbqa&v=xxx3Fn7EowU
I'm trying to build my project with the debug buildType as explained in the video:
debug {
minifyEnabled true
useProguard false
}
I'm getting a bunch of warnings and then this this error when building:
Error:Execution failed for task 'app:transformClassesWithNewClassShrinkerForMyAppNameGoesHereDebug'.
Warnings found during shrinking, please use -dontwarn or -ignorewarnings to suppress them.
With Proguard, I would add the appropriate -dontwarn necessary in the proguard project file. Is there a Shrinker project file somewhere that I can add -dontwarn statements?
I found some documentation on this. Turns out it uses the same configuration files as Proguard. Here is the relevant part from the doc:
The built-in shrinker can only remove dead code, it does not obfuscate or optimize. It can be configured using the same files as ProGuard, but will ignore all flags related to obfuscation or optimization. Unlike ProGuard, we support using the built-in shrinker together with Instant Run.
Also, here is a sample configuration for reference:
buildTypes {
debug {
minifyEnabled true
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
I'm making the transfer to Android Studio 1.0.1. I've also been avoiding using the android-support-v7 due to the problem that I'm encountering described in this link. However now I want to include material design and need to use the appcompat.
The two devices I test on are affected by the bug in the link above, so I have a few ideas of how to solve this. Please give me advice on if these will work, because I'm not familiar with how Proguard works yet due to never having used it (I've read through the documentation)
I believe I just need to include these lines to make appcompat libraries work on the affected Samsung devices:
# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}
1) in the buildTypes create a "debug" section. Set minifyEnabled to "true" and only include the file with the lines specified in the link above in the proguard file specified. Don't include the default proguard file because while debugging I don't want all of the code to be minimized, I just want to rename the affected classes.
I guess I only have one idea. Will this work? I'm going to try it and report back...
If you are debugging on samsung devices running 4.2.2 and are having issues, ensure you add the following lines of code to the 'proguard-android.txt' if you are using proguard, or create your own text file (as I did) and point to that file in your build.gradle
# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}
Here's what my gradle file looks like. 'samsung-alteration.txt' contains only the above code snippet
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('samsung-alteration.txt')
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
Hope this helps some of yinz!
I have a problem that Proguard strips out methods of my debug APK (I need to run proguard on debug beccause of method dex file limit), even if they are used in the Test apk. E.g. i use GSON addProeprty method in Unit test, but not in the App apk. This method gets stripped away and causes the test to fail. But i do not want to configure proguard to just keep all of GSOn because of the dex file limit, but also do not want to list all methods seperately. is there a way to tell rpguard to consider the unit tests as source code entry points?
This is what I did.
Add a custom proguard rules file.
/project/app/proguard-test-rules.pro
# Proguard rules that are applied to your test apk/code.
-ignorewarnings
-keepattributes *Annotation*
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
-dontwarn org.hamcrest.**
-dontwarn com.squareup.javawriter.JavaWriter
# Uncomment this if you use Mockito
#-dontwarn org.mockito.**
The add the following to your build.gradle for your app. To use the proguard file when testing.
/project/app/build.gradle
android {
debug {
minifyEnabled true
testProguardFile 'proguard-test-rules.pro'
}
}
None of the above answers did the trick for me. I had two issues: I needed to also use the default proguard file for testing, and my default proguard file was wrong.
To use the default proguard file, in addition to your own:
android {
debug {
minifyEnabled true
testProguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project-test.pro'
}
}
The default proguard file (and all of the tools/proguard folder) is apparently not replaced by default when you update the SDK tools through Android studio. My machine was using an outdated config file, which was causing weird proguard issues. To update proguard's default config, replace ~/Library/Android/Sdk/tools/proguard/proguard-android.txt with this.
Instrumentation tests (and others?) do not use the same proguard file as your debug/release apk's. You might try setting the testProguardFile option inside the debug and release blocks. This test-specific proguard file can be very permissive because it's not being used for the debug/release apk's.
I've solved this problem in my build by having an additional "dev" buildType where I enable proguard, but configure it to keep all code in my own package, and a few specific library classes that happen to be used from tests only. I also disable obfuscation in the dev buildType so that it can be debugged from an IDE.
For debug and release builds I use my "real" proguard settings including obfuscation and optimizations.