Reputation: 9123
Android's new R8 compiler detects and safely removes unused classes, fields, methods, and attributes from your app and its library dependencies among other things.
Does it also remove Log statements? E.g. if I build my Release APK, ready for launch, am I safe to leave my Log statements in my app?
Log.d("LogStatement", variable.toString())
or do I have to remove them every time I upload/update my app to Google Play?
Upvotes: 2
Views: 1051
Reputation: 21
Short answer: it depends.
As you can see at this issue for R8: https://issuetracker.google.com/issues/73708157
It depends on which logger you are using. And of course you have to define the proper ProGuard-rules.
When using the ProGuard-rules as mentioned by Younes Charfaoui, the call to the logger will be removed. This works only, when using plain Strings:
Log.d("LogTag", "My log statement");
--> will be properly removed.
But when using (automatic) StringBuilder at logging:
Log.d("LogTag", "My log statement will show some variable: " + variable);
only the call to the logger will be removed.
This means, the StringBuilder-part will remain visible in the resulting ByteCode.
You have to watch out, not to use any automatic StringBuilders.
Another example:
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d("MyFragment::onCreate", "will be removed"); // will be dropped
Log.d("MyFragment::onCreate::", savedInstanceState.toString()); // call for toString() will remain
}
see:
invoke-virtual {p1}, Landroid/os/Bundle;->toString()Ljava/lang/String;
There are ProGuard rules which are only supported by ProGuard and not yet by R8, which would easily remove the remaining StringBuilders: assumenoexternalsideeffects, assumenoexternalreturnvalues.
When using logging with automatic StringBuilder you have:
To really make sure, that your logging code is removed with R8 you have two options:
logger.debug("My log statement will show some variable: {} and maybe another one: {}", variable1, variable2);
if (Logger.SHOW_LOG) {
logger.debug("My log statement will show some variable: " + variable1 + " and maybe another one: " + variable2);
}
also see: http://www.slf4j.org/faq.html#logging_performance
If you also think, that this should be working with R8 the same as it did with ProGuard, please star one of the following issues:
Add support for Proguard 6 -assumenoexternalsideeffects optimization option
Add support for Proguard 6 -assumenoexternalreturnvalues optimization option
Improve unused StringBuilder elimination
Upvotes: 2
Reputation: 398
I am not sure, if you are still looking for an answer for this, but, it is not removed, if you inspect the apk using apk analyzer (use the mapping file for readability), you would see the Log class does exist. And like @Younes Charfaoui mentioned you can add those proguard rules to remove it.
Upvotes: 0
Reputation: 1161
No, at all, you can do this via Proguard Tools. In build.gradle
you can enable Proguard
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
Modify the proguard-rules.pro file, which should live under your standard Android app directory:
-assumenosideeffects class android.util.Log {
public static *** v(...);
public static *** d(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
}
I hope this answer helps you.
Upvotes: 1