Things to care while using Proguard in Android application

While writing the code for your Android application, there may be some lines of codes that are useless and will result in increasing the size of your application APK. Apart from the unused code, there are many libraries that you may have used in your application but you have not used all the functions that a particular library is providing. Also, you may have written some code that is of no use in the future and you forgot to remove that code. These things are responsible for increasing the size of the APK of your application.

In order to reduce the size of the APK, Android provides the functionality of Proguard. Using Proguard helps in achieving the below three functionalities:

  1. Minify the code
  2. Obfuscate the code
  3. Optimize the code

So, the Proguard will help you in reducing the size of your APK, remove the unused classes and methods and also make your application difficult to reverse engineer.

But with great power, comes great responsibility

So, while using Proguard you should take care of certain things. In this blog, we will look upon certain things that must be taken care of while using Proguard in our Android Application. So, let’s start with the first point.

Exclude Proguard from Data Classes

In almost every Android application, there is some kind of Data or Model class that is used to fetch some data from the remote database. So, if you are using Proguard then the Progurde will change the class name, variable name, and method name. For example, if you are having a class named User and it contains variable like firstName and lastName, then the Proguard will change your User class name as A or something like that. At the same time, your variable names may be changed to some x, y, z. So, if you want to store the data of the same variable stored, in the Database you will get a run time exception as no such field will be found in the database.

In order to avoid this, you should tell the Proguard to keep the variables and methods of the User class and don’t obfuscate it. To do so, add the below line in your proguard-rules.pro file:

-keep class your.fully.qualified.class.name.** { *; }

By adding the above line, no obfuscation and optimization of the code will be performed by the Proguard in the desired class.

Don’t use Fragment TAGs while using Proguard

Most of the problems that are being faced in Proguard are due to its obfuscation property. Same as in the case of Fragments.

Whenever we make a Fragment we declare some String TAG as FragmentName.class.getSimpleName() and use this TAG in our Fragment. But if you are using Proguard, then this may lead to some bug in your application. For example, let’s we have two fragments named Fragement1 in the firstfragment package and Fragment2 in the secondfragment package. So, the Proguard will change the firstfragment package as “a” and secondfragment package as “b”, but at the same time the Proguard can change the name of the Fragment1 as “a”(as the package and Fragments are different so names can be same) and Fragment2 as “a” also because Fragment2 is different package. But at this time if you are using FragmentName.class.getSimpleName() then this will create confusion because the Fragment1.class.getSimpleName() has been changed to a.class.getSimpleName() and Fragment2.class.getSimpleName() has been changed to a.class.getSimpleName(). Both TAG value will get confused about which fragment is being called. So, using FragmentName.class.getSimpleName() should be avoided.

Handle Reflection

Whenever your classes and methods are accessed dynamically i.e. by using reflection, then you should take care of Obfuscation of your class or method. For example, if you are referencing your code from the XML file (which normally uses reflection) and at the same time if you are using Proguard then the Proguard will change your class name to “a” or something like that in the XML code, no changes will be made and this will result in class not found exception or method not found exception.

So, always keep the class using reflection in your Proguard rules.

Handle View

Whenever you create your own view in Android application make sure the view class that you are making is kept in the Proguard rule otherwise you will get class not found exception.

For example, if you are creating a simple view name com.mindorks.simpleview and if you are using this view in your XML file, then the Proguard will change your view class name as “a” or something like that and in the XML, your code is calling com.mindorks.simpleview and there is no such class as it has changed to “a”.

So, always make sure to keep your Views in the Proguard rules. You can tell the Proguard to keep the classes that are extending View by adding the below lines in your proguard-rules.pro file:

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

Adding Proguard rules for libraries

In our Android Application, we use a number of open source libraries. But at the same time if you are using Progurad then you must include the Proguard rules of the libraries you are using if any.

To find the Proguard rules of a library, you can read the README.md file of the library that you have used and add the given Proguard rules in your application. A sample of Proguard rules of Retrofit library can be found here.

Keep Native codes

While using native code in your Android application i.e. while using c++ code in your Android application, you must be aware of the consequences of the obfuscation by Proguard. In general, the Proguard can only inspect the Java class. So, if you are calling some Java method from the c++ code and that method has been obfuscated by the Proguard, then the JNI will produce method not found exception.

So, if you are calling some methods from the native code then you must keep those methods in the Proguard rules by adding the below line in the proguard-rules.pro file:

-keepclasseswithmembernames class * { native <methods>; }

Resource opening from JAR/APK

In Java, we can load resources from the JAR file or even some libraries load resources from the APK file also. This is of no problem, but whenever we are using Proguard then these resources file names will be changed by the Proguard and these files will not be found in the desired package.

So, you should keep the names of classes that load resources from the APK in your Proguard rules.

Bonus

If you are done with the optimization of your code then you can put all the files in the root package as this will reduce the usage of fully qualified names like com.mindorks.proguard.example. To use this feature, add the below line in your proguard-rules.pro file:

-repackageclasses

Conclusion

In this blog, we learned about the things that should be taken care of while using Proguard in our Android application. We learned how to keep certain classes in the Proguard. Also, we learned how to add the Proguard rules of some third party libraries.

You can check our video of “Things to take care while using Proguard in Android App” here.

Also, if you want to know “How to use Proguard in our Application — Coding”, then you can check our video here. Also, you can read about the same at MindOrks.

Keep Learning :)

Team MindOrks!