Usually one of the first things I create in a new ...
# android
s
Usually one of the first things I create in a new android project is a L class. Which makes logging easier and also prevents logs to go into a non-debug versions
Copy code
object L {

    private const val TAG = "FOOBAR"

    fun e(log: String) {
        if (BuildConfig.DEBUG) {
            Log.e(TAG, log)
        }
    }
    ...
}
h
Ah... cool! I use to do it too
t
I would use something like this instead. This way the log message is removed completely from the code in a release build.
Copy code
object L {

    const val TAG = "FOOBAR"

    inline fun e(log: () -> String) {
        if (BuildConfig.DEBUG) {
            Log.e(TAG, log())
        }
    }
    ...
}

L.e { "message to log" }
👍 1
s
I would think that proguard/R8 will remove it if activated. But I didn't dig into it, yet. If proguard doesn't remove it I'm very happy to use your approach in my existing and future projects 🙂
h
image.png
image.png
t
If you concat strings (or string templates) for the log message it will be converted to a StringBuilder in the bytecode. Proguard/R8 won’t remove those StringBuilders, even if they aren’t used. My example places the log message within the
if
statement. The compiled code will look like this:
Copy code
if (false) {
    Log.e(TAG, "message to log")
}
That way all the code is removed.
h
ProGuard remove it
t
ProGuard remove it
Maybe it removes the logs but it does NOT remove the string concatenation that is needed for the message. So if someone decompiles your APK the log messages are still there
h
Got it
s
@Thomas Thanks for the explanation, now it's clear. I'm going to use that version from now on.
a
We’ve used Square’s Timber library to log everything in debug builds to Logcat, but for release, only log Warning or above, and only to a rolling log file in the user’s private storage (not to Logcat). We give users an option to report a problem thru the app by email. We include some relevant info about the device and app config settings, and the log file (zipped). We find we always need to tweak what we include in the logs, but still, paired with any context from the user’s email, they have been invaluable.
h
Really cool @andym
f
Note that if you use that, you cannot use $it or ${myvar} as it is probable that it slow down the application a lot
t
@florent do you mean my example? The idea is to remove the logging completely. It can not slow down the application if all of the code is removed.
f
But L.e { "message to log" } will stay so the string will be generated even if it isn't displayed. So unless I am missing something, the system will still be slow down when complex string are created using for example $it to print a complex data class.
t
@florent no, that's incorrect. The lambda will be inlined within the
if (false) { ... }
statement so it will be removed completely when compiling a release build. That's the point of using this method instead of the original one that was posted.
f
But you stated that the concatenation will stay, that's where the performance will get reduced
t
@florent that was for the original post. The method I shared removes it completely. You can try it out for yourself by decompiling the APK and see the difference.