Android ProGuard: Most Aggressive Optimizations
Asked Answered
F

3

74

Android's official proguard documentation shows two primary optimizations:

  • set minifyEnabled to true
  • use proguard-android-optimize.txt instead of proguard-android.txt

Are these two the most aggressive possible settings?

I am writing an android library and need to make sure when people use my library that my code doesn't break. (I know there are rules I can put in my library to counter the proguard configuration set on the app that uses the library, but I don't want to do that if I don't have to.)

Freddafreddi answered 10/2, 2016 at 17:17 Comment(4)
Are you going to upload your library at jcenter? Because I don't think ProGuard will affect in that case. You might take a look at some of the libraries already working great - Material Dialogs. Or just check out android-arsenal.comDerringdo
I wish every library author would take so much care about ProGuard. More often than not, we needed to figure out the ProGuard rules for third-party libraries ourselves.Acierate
I'm curious what you're anticipating will turn up from this question. An external resource? A recommendation? Technically, your question could be answered with a "yes" or "no", but I suspect you're looking for more?Dwt
I'm hoping for 1. yes, here's how it can be further optimized OR 2. No, heres a logical proof as to why not or a credible source saying that it cant.Freddafreddi
B
76

Remember that the best ProGuard configuration - is a configuration with a minimum of exceptions. Under the exceptions I understand:

 -keepclassmembers class * extends android.content.Context {
    public void *(android.view.View);
    public void *(android.view.MenuItem);
 }

Let's walk through proguard-android-optimize.txt and look on optimisation/obfuscation options.

For detailed description of ProGuard options I use this

-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* This - list of possible optimisation, ! mean negate, so this optimization is not used

-optimizationpasses 5 Specifies the number of optimization passes to be performed. By default, a single pass is performed. Multiple passes may result in further improvements. If no improvements are found after an optimization pass, the optimization is ended. Only applicable when optimizing.
Usage: OK, and looks like that default 5 passes is enough

-allowaccessmodification Specifies that the access modifiers of classes and class members may be broadened during processing. This can improve the results of the optimization step.
Usage: OK, yes looks like improve optimization

-dontpreverify When targeting Android, preverifing is not necessary, so dontpreverify turn it off to reduce the processing time a bit. But this option is not impact on unbreakability of code.
Usage: OK, just to little bit reduse processing time

-dontusemixedcaseclassnames Specifies not to generate mixed-case class names while obfuscating. By default, obfuscated class names can contain a mix of upper-case characters and lower-case characters. This creates perfectly acceptable and usable jars.
Usage: QUESTIONABLE, I can't find exact reason why this option added, but looks like change class name from abcdef to AbCdEf doesn't make code unbreakable

-dontskipnonpubliclibraryclasses Specifies not to ignore non-public library classes. As of version 4.5, this is the default setting.
Usage: OK, very useful

The following options aren't include to proguard-android-optimize.txt:

-mergeinterfacesaggressively Specifies that interfaces may be merged, even if their implementing classes don't implement all interface methods... setting this option can reduce the performance of the processed code on some JVMs
Usage: BAD, look dangerous for Android, don't included into config, sumular of prohibition of class/merging/ in optimizations

-overloadaggressively Specifies to apply aggressive overloading while obfuscating. Multiple fields and methods can then get the same names, as long as their arguments and return types are different, as required by Java bytecode (not just their arguments, as required by the Java language)
Usage: BAD, Google's Dalvik VM can't handle overloaded static fields.

So I know only one more useful for obfuscation and non dangerous option:
-repackageclasses ''

-repackageclasses '' Specifies to repackage all class files that are renamed, by moving them into the single given package. Without argument or with an empty string (''), the package is removed completely. This option overrides the -flattenpackagehierarchy option.
Usage: OK, Used by Google, so look like we at least have found the option which we can add to our config

Also please notice about decoding stack traces. ProGuard also removes the filename and line numbers from the stacktrace. This makes finding errors very complicated. You can keep the line numbers by adding the following code to your config:

-renamesourcefileattribute SourceFile 
-keepattributes SourceFile,LineNumberTable

This will keep the line numbers but replace the filename in the stacktrace with "SourceFile".

Also do not forget that the ProGuard looks vulnerable because it does not encrypt the string resources, so consider using DexGuard or encrypt important strings (like tokens, urls) themselves.

Baird answered 19/2, 2016 at 15:55 Comment(1)
It is important to note for library maintainers that -allowaccessmodification may result in some of your hidden methods/members/classes becoming exposed (public), which is probably not what you want to do.Hoeve
D
8

According to the comment from the optimization file, the optimizations introduce certain risks and if used, the app must be tested thoroughly. According to my experience, it is necessary to disable code/simplification/advanced, because it caused final local variables which were initialized outside a lambda being NULL inside the lambda. It was very difficult to debug and find. Therefore my optimization settings are as follows:

-optimizations !code/simplification/cast,!code/simplification/advanced,!field/*,!class/merging/*,!method/removal/parameter,!method/propagation/parameter

Note that code/simplification/arithmetic must be also disabled if you target Android 2.0 and lower (which is very unlikely). Besides that, I also had to disable method/removal/parameter and method/propagation/parameter, because these implicitly enable code/simplification/advanced (see ProGuard manual for more info).

Deidredeific answered 13/7, 2017 at 9:12 Comment(0)
E
-1

In libminecraft 1.15.2 zero, the first Minecraft version to use the new libminecraft's advanced-technology whole-program optimization, I only used gson, inlining, and code optimizations. This is done to mitigate the potentially destabilizing effects of using full optimization.

Now we had Minecraft 1.16.2 and ProGuard 7.0.0, I used full optimizations without any stability problems (I actually stacked ProGuard with Allatori, and still not run into stability problems, since Allatori does better control and data flow optimizations than ProGuard).

I ran ProGuard three times in libminecraft 1.16.2 heavy. Once with 5 passes of code optimizations only, once with all non-code optimizations, and once with 2 passes of code optimizations only. Additionally, I used Allatori for the final pass of optimization since it performs very high-quality control and data flow optimizations.

Electrocorticogram answered 3/9, 2020 at 9:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.