2. The Debugger
The Android SDK makes the use of the Eclipse debugger completely
transparent, so let’s use it to see what’s going wrong with our program.
We’ll put a breakpoint at the line we just entered, so the debugger will
break there when we run the program. Eclipse gives us three ways to
toggle a breakpoint:
Use the menus. Select the line you want to toggle and choose
Run → Toggle Breakpoint.
Use the keyboard. Select the line you want to toggle and key
Ctrl-Shift-B.
Double-click in the left margin of the editor window at the
line you want to toggle (my favorite method).
Whatever way you choose, you end up with a breakpoint mark in the
left margin of the editor window, as shown in Figure 8.
To invoke the Debugger, choose Run → Debug → Android Application
from the Eclipse menu. Eclipse and the Android SDK do what they did before (build the
program if necessary, convert to Dalvik, invoke the emulator, load your
program, and start it running). You may get a window in the Emulator
that says “Waiting for Debugger: Application DebugTest is waiting for
the Debugger to connect.” If you do, just wait a few seconds and the
Debugger should finish initializing, the window will disappear, and
you’ll see the DebugTest screen.
Now enter http://www.oreilly.com and click the Go
button. DebugTest starts executing and breaks at the breakpoint. Eclipse
automatically changes to the Debug Perspective, showing you panes that apply to
debugging your application. Starting from the upper left and moving down
the window, left to right, these are:
Debug
The Debug pane has a single tab (Debug) that shows a
trace of recent execution. It should show that you are at a
breakpoint in a Dalvik thread running DebugTest, at Java line 19.
In its toolbar, this pane also contains the buttons for Resume,
Suspend, Terminate, Step Into, Step Over, Step Return, etc.
Variables and Breakpoints
This pane has two tabs, the most useful of which is
Variables, where you can see the current value of variables that
are in scope. So far it’s showing values for this and v.
Editor
This contains a tab for each of the source files that
you had open in the Java Perspective. The currently displayed tab
should show DebugTest.java,
highlighting the current breakpoint (line 19).
Outline
This shows the structure of your application. DebugTest
is simple, so it shows only one method, OnCreate.
Console/Tasks/Properties
This pane has tabs for each of these views, which don’t
contain much that’s interesting at the moment. The Console is the
most useful, and in some debug situations can have important
information telling you what is (or isn’t) happening.
Logcat
This is the subject of the next section: the contents of the
Android logcat log, with buttons to filter the content.
Focusing on the Editor pane, which shows us stopped at line 19,
let’s use the Step Over button (in the Debug toolbar in the pane above)
to step the program one line, to line 20. Now sURL appears in the Variables Pane, and it has
the right value, http://www.oreilly.com. Step once more and you
can tell something’s wrong: we expected the program to take the first
branch of the if, and it took the second instead.
That’s why http:// is appearing twice
in the URL string. If we step once more we can see that, as the value of
sURL changes in the Variables
Pane.
To find out why, let’s use another debug feature of Eclipse. From
the menu, choose Window → Show View → Display. A new Display tab is
added to the lower-left pane, and comes to the front. As long as the
Debugger is running, you can type any variable or expression that’s in
scope into this window to display the variable’s value or execute the
expression. We should be curious about the expression we’re comparing
the user’s URL to, sURL.substring(0,6). So cut and paste this
method call from the Editor pane into the Display tab, select the
expression, right-click, and choose Display from the pop-up menu.
Eclipse evaluates the expression and displays the result in the pane—and
what do you know, it’s http:/, with
the last / missing, as shown in Figure 9. This problem may be
typical of errors that programmers encounter with the use of Java’s
substring method, because its second
parameter represents the location of the last character, not the count
of characters, as in some other languages. We change the 6 to 7, and the
program works fine.