ProGuard pointers for your Android app
Obfuscate the source code and shrink your app
There is no better place to familiarize yourself with Proguard than the official docs. Do give it a read, this post is intended to summarize some of the ideas mentioned in the post.
What is Proguard?
Proguard is a tool that lets you achieve the following:
- Shrink the code: Remove unused code paths which reduces the binary size
- Obfuscate the code: Rename the names of classes, fields, member functions, etc. which makes it difficult to reverse engineer
- Optimize the code: Such as inlining methods
How to enable Proguard?
In your app's build.gradle.kts file, do the following:
android {
buildTypes {
getByName("release") {
isMinifyEnabled = true
isDebuggable = false
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}Note: It is applied on a release build, and when isMinifyEnabled is set to true, it activates the proguard-rules.pro and you can tailor it as per your need. Code Shrinking is enabled by default whenever minify is enabled. You can read more about how R8 does this heavy lifting for you.
For most situations, the default proguard-android- optimize.txt is sufficient to remove unused source files. However, there are scenarios where your code relies on a 3rd party library or even native code with sophisticated scenarios where you don't want to obfuscate all of them as some code paths will be needed up at runtime.
By default, if you compile and run the app, you may notice some things don't work. In order to fix these errors and enforce R8 to keep certain code, you may need to add custom rules in order to avoid compile time and runtime issues.
To output, a full report of all the rules that R8 applies when building your project, include the following in your module’s proguard-rules.pro file:
// You can specify any path and filename.
-printconfiguration ~/tmp/full-r8-config.txtHow to Customize which code to keep?
Highly recommend referring to this to learn more about customizing the file. To fix errors and force R8 to retain code in the ProGuard rules file.
Class
Preserves the class as is. Alternatively, use @keep on the class to do the same.
-keep public class MyClassIn order to preserve the class and all of its members
-keep class com.org.sample.MyClass.** { *; }Class Members
Preserves the class members but the class while shrinking
-keepclassmembers class com.org.sample.MyClass{
public *;
}Class and Members
Preserves all the same names of the class and members of a class if it's being used in the code i.e. if the class is not used it would be shrunk by proguard but not obfuscated because it has already been shrunk there is no need of obfuscation
-keepnames class com.org.sample.MyModuleAttributes
Preserves the annotations of each class.
-keepattributes *Annotation*3rd party library
When using a library, such as retrofit to avoid warnings you can consider
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }Sample proguard rules for retrofit can be found here
Native Code
Preserves the methods in native code
-keepclasseswithmembernames class * { native <methods>; }Miscellaneous
In some rare scenarios, where you only want to obfuscate the code but not shrink the resources you should consider adding the following to the proguard rules
-dontshrink
-dontoptimizeTo increase the number of cycles in optimization for e.g., optimize it again to a certain number of cycles use,
-optimizationpasses 5To further optimize at a granular level consider the below
for classes
-optimizations class/marking/finalfor private fields
-optimizations field/marking/privateRepackage all the files in the root package to reduce the usage of fully qualified names
-repackageclasses