A while ago I wrote about removing the logs from release builds using Proguard. As usual, I’ve found a gotcha that might cost you a couple hours of head scratching.
Let’s say that we have a code like this somewhere:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
doNotRunOnProduction() method might perform some expensive database query, send some data over the network or launch intercontinental missiles – anyways do something that you don’t want to happen in production app. If you run the code on the debug build you’ll of course get the following logs.
Now, let’s add Proguard config that removes all the
1 2 3
We might expect the
Log.e() call to be gone as well, but alas, here is what we get:
The key point to understanding what is happening here is the fact that the Proguard does not operate on the source code, but on the compiled bytecode. In this case, what the Proguard processes is more like this code:
1 2 3 4 5 6 7
One might argue that the temporary variable is not used and Proguard should remove it as well. Actually that might happen if you add some other Proguard configuration settings, but the point of this blog post is that when you specify that you want to remove calls to
Log.d(), you shouldn’t expect that any other calls will be affected. They might, but if your code really launches the missiles (or does something with similar effect for your users), you don’t want to bet on this.