I was reading the docs about shrinking, obfuscating and optimising for a release build using build.gradle for an Android app. In one section of the docs, proguard-android.txt is used as the defauly ProGuard file:
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
and in another section, proguard-android-optimize.txt is used:
android {
...
buildTypes {
release {
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
}
There doesn't seem to be an explanation of what the difference between these are, and I can't find any information. Can someone explain what the differences are and when you would use proguard-android-optimize.txt vs proguard-android.txt?
Thanks :)
Take a look at the Android source code over here.
Optimizations: If you don't want to optimize, use the
proguard-android.txt configuration file instead of this one, which
turns off the optimization flags. Adding optimization introduces
certain risks, since for example not all optimizations performed by
ProGuard works on all versions of Dalvik. The following flags turn
off various optimizations known to have issues, but the list may not
be complete or up to date. (The "arithmetic" optimization can be
used if you are only targeting Android 2.0 or later.) Make sure you
test thoroughly if you go this route.
Also, this answer is a pretty good read as well.
Related
In build.gradle (app) file we have this by default,
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
According to https://developer.android.com/studio/build/shrink-code,
minifyEnabled true make the code more secure (making it hard to reverse engineer) and also shrink the size in release build, which we use for publishing the app.
I know that using minifyEnabled true makes compile time longer, but usually debug builds are used for development and testing, which is not affected anyways.
What I'm looking for is that, what are the disadvantages (such as performance impacts) cause by using minifyEnabled true at runtime. I'm not worried about the build time of a release build.
Google Play Console also recommending us to enable it therefore I'm wondering why is minifyEnabled is disabled by default.
By adding minifyEnabled true in your release build you can obfuscate code but it is set to false by default in release builds because if set true it shall require proguard rules to be written to tell the compiler which classes are to be ignored while obfuscating the code. If minifyEnabled is set to true by default and the developer forgets to add proguard rules, it can lead to runtime crashes.
However, setting minifyEnabled to true and shrinkResources to true can reduce your apk size.
As NIKHIL AGGARWAL said, setting minifyEnabled to true can lead to runtime crashes.
You should research each used library so that include their ProGuard rules into your project. Also sometimes after Gradle or libraries upgrade you should again check ProGuard rules and accordingly update them in your project.
You should add data classes of your network model to ProGuard.
You should check your release build on several devices/emulators with different Android versions to understand where it can crash. Debugging in release build is difficult and with obfuscation it becomes a nightmare.
However after you set minifyEnabled = true and avoid crashes you will decrease apk size and impede to cracking attempts.
when I'm trying to build the application, Both release and debug are creating huge data(in MB).[this is my gradle file. I have created a new project and nothing is been created in it but still producing 2-3 MB..]
can anyone please help me out?
This is because of the dependencies libraries especially the support libraries. If you create your application without the support libraries, your application will not weight about 1 MB. Which means you need to use Activity instead of AppCompatActivity and use ListView instead of RecyclerView and etc.
Your basic application with support libraries will be weight about > 2 MB this is the trade-off of all the features support libraries gives you.
Update:
Also delete one or more of these to save some space if you don't use them: glide,circle image view, cardview, constraint layout
end Update
This is basic support library size, maybe you are using some drawable which has some size of around 1MB.
Anyways, you can reduct apk size by shrinking resources and enabling minify.
app/build.gradle
android{
.
.
buildTypes {
debug {
shrinkResources true
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
shrinkResources true
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
I want to build an .aar library and proguard classes, but my library proguard file doesn't work, and I can see clear classes.
Here is my proguard file:
android {
buildTypes {
release {
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules-my-lib.pro'
}
}
}
and app/build.gradle:
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
While you can probably shrink and obfuscate the library itself, the usual practice is to leave minifyEnabled as false and provide the proguard configuration to the application, using consumerProguardFiles instead of proguardFiles.
This means that the minification is applied only once, on the whole application, using the merged configuration from the app's proguardFiles and the libraries consumerProguardFiles. This is usually more efficient because parts of the libraries not actually used by the application can be removed.
Create a Android Studio Project and convert it to library Follow this link. Build and Execute the command Generate APK, .aar file will be created in release/debug folder.
Write the proguard rules as similar to APK, it will apply to .aar file also.
I hope this helps
I see that the Android Plugin for Gradle has a minifyEnabled property as well as a useProguard property, as follows:
android {
buildTypes {
debug {
minifyEnabled true
useProguard false
}
release {
minifyEnabled true
useProguard true
}
}
}
What's the difference between these two properties? Or, rather, what's the meaning of each?
Quoting from tools.android.com:
Built-in shrinker
Version 2.0 of Android Plugin for Gradle ships with an experimental
built-in code shrinker, which can be used instead of ProGuard. The
built-in shrinker supports fast incremental runs and is meant to speed
up iteration cycles. It can be enabled using the following code
snippet:
android {
buildTypes {
debug {
minifyEnabled true
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
}
}
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: depending on the project, it may significantly decrease
the initial build and install time. Any methods that become reachable
after a code change will appear as newly added to the program and
prevent an Instant Run hotswap.
You don't need useProguard true anymore.
Code shrinking with R8 is enabled by default when you set the minifyEnabled property to true.
When you build your project using Android Gradle plugin 3.4.0 or higher, the plugin no longer uses ProGuard to perform compile-time code optimization. Instead, the plugin works with the R8 compiler to handle the tasks according to the official document.
If you want to use ProGuard instead of R8. Add this line in the gradle.properties file
android.enableR8=false
I set minifyEnabled true for my release buildType and it removed an entire enum which it thougt to be unused code i guess. This made my app crash due to a NoSuchFieldException. Took me 4 hours to find the reason for this crash. 0/10 can not recommend minifyEnabled.
Just enable minifyEnabled will have code both optimized and obfuscated.
This is because useProguard true is default so no need to set it explicitly.
See also:
Obfuscation in Android Studio
When I do not minify my app I reach the maximum method count and building the dex file fails. This can be avoided by enabling minify in build.gradle. The downside, however, is that now the code gets obfuscated. This is OK for the Release build but it is problematic for a Debug build.
Is there a way to tell gradle to minify a Debug build but not obfuscate it?
minifyEnabled true
is just a shortcut for:
postprocessing {
removeUnusedCode true
obfuscate true
optimizeCode true
}
So, if you want to minify without obfuscating, replace minifyEnabled true with:
postprocessing {
removeUnusedCode true
obfuscate false // <--
optimizeCode true
}
Additionally, the compiler will complain if you have shrinkResources true. The equivalent postprocessing field is removeUnusedResources true, i.e:
postprocessing {
removeUnusedCode true
removeUnusedResources true // <--
obfuscate false
optimizeCode true
}
Contrary to other answers, useProguard false does not disable obfuscation; it changes the obfuscation engine from ProGuard to R8.
Yes, you can use ProGuard to minify debug builds.
The key is to use -dontobfuscate option in ProGuard configuration for debug build.
Use this setting in build.gradle:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro',
'proguard-rules-debug.pro'
}
}
Write your release ProGuard configuration to proguard-rules.pro.
Use the same configuration for release and debug. This way you ensure that no necessary code is stripped away. And debug minification doesn't break the build.
Add extra ProGuard config file proguard-rules-debug.pro for debug build. It should contain rules used only for debug. In this case add only:
-dontobfuscate
Tomik's answer is technically correct, but it doesn't support using Instant Run for your builds. As pointed out in the official guide on code-shrinking:
Enable code shrinking with Instant Run If code shrinking is important
to you while incrementally building your app, try the experimental
code shrinker that's built into the Android plugin for Gradle. This
shrinker supports Instant Run, unlike ProGuard.
You can configure the Android plugin shrinker using the same
configuration files as ProGuard. However, the Android plugin shrinker
does not obfuscate or optimize your codeāit only removes unused code.
So you should use it for your debug builds only, and enable ProGuard
for your release builds so your release APK's code is obfuscated and
optimized.
So the proper solution would be to setup your debug build like this:
android {
buildTypes {
debug {
minifyEnabled true
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
This way the code in your debug build doesn't get optimized nor obfuscated, but will get shrunk. This also applies when using Instant Run.
A simple solution is to add minifyEnabled true and useProguard false inside the build configuration. But code shrinking is not recommended for debug builds from official docs Be aware that code shrinking slows down the build time, so you should avoid using it on your debug build if possible.
Reference https://developer.android.com/studio/build/shrink-code.html