The Android SDK takes full advantage of the features built into the
Eclipse IDE, including those in the
Eclipse text editor, which is customized for Java source code development.
Let’s use a simple application as an example of some of that editor’s
features. If you’re already an expert on using Eclipse for Java
development, you can skip this section. If you’re new to Eclipse (or new
to Java), there are some hints here that will speed up your development of
Android applications.
1. Java Errors
We’ve created a new Android project called DebugTest, using
Eclipse and the Android SDK (File → New → Project → Android Project).
When you do that, and open the Java source file the SDK created for you,
you get a central pane that looks like Figure 1. This is the Eclipse Java
text editor, and it is already doing its job to point out errors in the
nascent application.
In this case, the error indication is in the left margin: the
little lightbulb and red X on line 11. Within that line, the editor has
underlined the R in R.layout.main to tell you specifically where
there’s a problem. Editors in Eclipse are smart enough to understand the
syntax of the language they are editing, and in this case, the error
flag is telling us there’s a problem with this part of the code. If we
use the mouse to hover over the R, we
get a pop up that gives us more information, as shown in Figure 2. If you hover your mouse
over the symbols in the left margin, you get the same pop up.
Notice also that there’s a little red indicator in the upper-right
area of the pane, indicating there is an error somewhere in this file,
and a little red open rectangle in the right margin. If this file were
big enough to need the vertical scroll bar, you could easily see the
locations of the errors in the file, and you could scroll to them by
dragging the scroll segment to the red rectangle. Eclipse makes it very
easy to see where it has found errors in your code.
A quick check of the Package Explorer pane shows that there’s no R.java file. Of course not! It doesn’t exist,
because we haven’t built the project yet, and that’s why resources under
R can’t be resolved. After we build
DebugTest (Project → Build All), the error goes away (both the red
underline and the symbols in the margin).
So let’s add some code for a simple application and see some of
Eclipse’s debug features. We’ll edit DebugTest.java and main.xml to add a label, a text box, a
WebView (we want some Internet action to give us more to look at), and a
button. The application will be a trivial browser, with the box being
the URL and the button being the trigger to go load the URL into the
WebView. We’ll throw in some intentional errors to see how Eclipse
handles them.
Our altered main.xml file now
looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter URL:"
/>
<EditText
android:id="@+id/URL"
android:layout_width="fill_parent"
android:layout_height="60.0dip"
android:maxLines="1"
<Button
android:id="@+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="60.0dip"
android:text="Go"
/>
<WebView
android:id="@+id/wvBrowser"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout>
and DebugTest.java looks like
this:
package com.oreilly.debug;
import android.app.Activity;
import android.os.Bundle;
public class DebugTest extends Activity {
private EditText txtURL;
private Button btnGo;
private WebView wvBrowser;
// Set up an onClick routine to gather URLs entered by the user
private final Button.OnClickListener btnGoOnClick = new Button.OnClickListener() {
public void onClick(View v) {
try {
wvBrowser.loadURL();
}
catch (Exception e) {}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Find the Views in the layout file
txtURL = (EditText) findViewById(R.id.txtURL);
btnGo = (Button) findViewById(R.id.btnGo);
btnGo.setOnClickListener(btnGoOnClick);
wvBrowser = (WebView) findViewById(R.id.wvBrowser);
}
}
If you type in these lines (instead of copying and pasting),
you’ll see that the editor tries to anticipate what you might type given
the context of where you are in the code. As you type “wvBrowser.”, for
example (including the final dot), the editor knows that
wvBrowser is a WebView, so it gives you a list of methods
and variables that WebViews have. This is a great feature that really
helps cut down on mistyped method and variable names. Once you’ve typed
or selected the method, the editor shows you the parameters for that
method, so you don’t have to look those up either.
Since we need to access the Internet to get web pages, we ask for
that permission in AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.oreilly.debug"
android:versionCode="1"
android:versionName="1.0.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".DebugTest"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
Looking at main.xml in the
Eclipse editor pane (now an XML editor, but with many of the same
features we saw in the Java editor), we see some errors (Figure 3).
A quick inspection confirms what the editor is telling us—that
there’s no close tag for the EditText. We type /> into line
17, and the red underlines immediately go away. Now that the EditText tag is fixed, we’re left with one
more error, shown in Figure 4.
It says we’re missing the end tag for LinearLayout, but we’re
really missing the slash that should start the end tag
</LinearLayout>. From the editor’s syntactical point
of view, it knows only that it expected to find a
</LinearLayout> before the next
<LinearLayout> tag or the end of the file, and it
didn’t find one. The error message is enough to cause us to look in the
right place and figure out what is really wrong.
Now that we have main.xml
fixed up, let’s look at the first part of DebugTest.java as it appears in Eclipse
(Figure 5). We can see from the
right scroll margin that there are a total of seven errors, and our
mouse is hovering over the error in the declaration of
btnGo.
Now for one of my favorite features of Eclipse. The source of the
error displayed in Figure 5-5, it
turns out, is that EditText can’t be resolved in the example, because we haven’t
imported the package that defines EditTexts. You could go look in the
Android documentation and find the right name for the library, but
Eclipse has a labor-saving feature that will find it for you. Just type
Ctrl-Shift-O (that’s the letter O) while the editor has focus, and
Eclipse will attempt to resolve all the unresolved references in the
file by finding appropriate libraries. With that one stroke, the
appropriate packages get imported for EditText, Button, and WebView (you
can’t see them in Figure 5-5,
because they’re hidden by the pop up), and those errors disappear from
the editing pane as well.
That leaves us with five more errors, so we scroll down as shown
in the Eclipse screenshot in Figure 6.
The four errors in lines 29, 32, 33, and 35 have the same source
as the one in Figure 5-2 and
will go away the first time we build the project with the new main.xml. Let’s fix the remaining error using
Eclipse’s help.
We currently have the mouse hovering over the error in line 19,
and the pop up says we’re trying to pass an Editable instead of a String
to the
loadURL(String)
method. That’s easy to fix: Editables have a toString method, like most objects, so we can
change onClick to look like
this:
public void onClick(View v) {
try {
wvBrowser.loadUrl(txtURL.getText().toString());
}
catch (Exception e) {}
}
Now we try to build and run the project (Run → Run → Android
Application), but Eclipse tells us we still have errors. It helpfully
lists all the problems found in the Problems tab, located in the pane at
the bottom of the Eclipse window. Figure 7 shows that tab.
Clicking on an error in the Problems tab takes us directly to the
corresponding line of source code in the Editing pane for DebugTest.java. A quick look at main.xml reveals the problem: we referred to
the text box as URL in
main.xml, and tried to find it as txtURL in the Java code. A quick fix to
main.xml, and the compile
completes.
Eclipse starts the Android emulator for us and loads our
application so it appears on the screen. The application runs—now to see
whether it produces correct results.
If you type in a URL like www.oreilly.com and click the Go button, you
get...an error. Instead of the web page you asked for, you see a page
that says “Web Page not Available.” Let’s try http://www.oreilly.com...ah, that works. So
let’s add code that checks whether the URL starts with http://, and if not, adds it:
public void onClick(View v) {
try {
String sURL = txtURL.getText().toString();
if(sURL.substring(0,6).equals("http://")) {
wvBrowser.loadUrl(sURL);
}else{
sURL = "http://" + sURL;
wvBrowser.loadUrl(sURL);
}
}
catch (Exception e) {}
}
Now when we run the program using www.oreilly.com as the URL, it works—but
http://www.oreilly.com doesn’t! Let’s
use the debugger to figure out why.