Using Eclipse Templates to Ease Android Logging
Adding logs to your Android source code is sometimes the only way to really understand what happens , especially in asynchronous situations.
If you are lazy like me, you may insert lazy logs like this one:
|
|
Instead of having less lazy code like:
|
|
But Eclipse can easily help you to avoid this and then the need to clean up your code after debbuging.
Everybody uses content assist in Eclipse. The CTRL+Space
shortcut alleviates
us from the need to type all those long field and method names that come out of
our imagination. With the Templates feature, it can even write code for us.
Templates are editable in the preferences. To see them, select
Window > Preferences
and then in the preferences dialog,
Java > Editor > Templates
. The window looks like this:
If you double click on a template you can edit it:
The template name is what you type in the Editor window before hitting
CTRL+Space
and that will make Eclipse propose you the template. I won’t go
into a full explanation of the syntax of the templates, but basically the
template name is replaced by the template pattern and the content between the
${}
is replaced either by what you type or by values computed by existing
macros. DZone gives you a good
Visual Guide to Template
listing most common macros.
Now we can create our templates for both adding the Log declarations at the beginning of our class as well as templates for inserting conditionally ran logs.
For the header, we create a template named alh
in Java types member
context
with the following pattern:
|
|
The different ${}
mean:
${:import(android.util.Log)}
: make sureandroid.util.Log
is imported.${enclosing_type}
: insert the name of the type (class) we’re in.${level}
: when inserting, put the cursor here and wait for the user to enter thelevel
variable.${cursor}
: leave the cursor here when the user hits theENTER
key.
With this template, inserting the log headers in a class is achievied with the following steps:
- type
alh
and hitSTRL+Space
. - select the template (first choice) and hit
ENTER
- enter the desired log level (
DEBUG
for instance) for the class and hitENTER
. - continue coding.
This is much simpler than copy-pasting the code from another class and replacing the class name and log level.
The following template, named alv
in the Java statement
context is for
inserting verbose logs:
|
|
The nice thing is that it inserts the name of the current method and wait just
after for your debug message. Just typing Enter
will leave a log like:
|
|
Wich may be just enough.
On this model, you can create ali
, ald
, ale
templates for the different
debug levels, or if you want to use String.format()
templates like :
|
|
Just adapt them to your needs.
Once you have finished debugging, if you change the LOG_LEVEL
of your class
from let’s say VERBOSE
to INFO
, all the alv
templates you’ve entered will
become dead code as the if
surrounding the log lines is always false
. This
is because it compares static variables, and this is just what we want. When we
compile for delivery, we want the compiler to optimize out all this code from
the binary.
However, the Java compiler will generate warnings for that. As it is not
possible to surround the log with a @SuppressWarnings()
attribute, you may
want to change the error level of dead code from Warning
to Ignore
. This is
done in Window > Preferences
,
Java > Compiler > Error/Warnings > Potential programming problems
.
When it’s time for delivery, you may want to change the LOG_LEVEL
of all
classes to a particular value. To do that, I personally use a slightly modified
version of the alh
header template:
|
|
That works with the DebugConstants
interface :
|
|
The way the modified alh
template works is the following:
- if the value of
DebugConstants.LOG_FORCE_GLOBAL
is 0, theLOG_LEVEL
variable contains the value of theLOG_LEVEL_LOCAL
variable. - if the value of
DebugConstants.LOG_FORCE_GLOBAL
is 1, theLOG_LEVEL
variable contains the value of theDebugConstants.LOG_LEVEL
variable.
By having inserted this template in my classes, even if at delivery time some of
the LOG_LEVEL_LOCAL
values are still set to Log.VERBOSE
, by setting
LOG_FORCE_GLOBAL
to 1, all log levels will be forced to Log.INFO
and all the
log code for deeper debugging levels will be removed by DCE (Dead Code
Elimination).
Now, there’s no more excuses to have sloppy logs in your Android code !