Once we've written the first iteration of our application code, we want to run and test it to identify potential problems or just be amazed at its glory. We have two ways we can achieve this:
We can run our application on a real device connected to the development PC via USB.
We can fire up the emulator that is included in the SDK and test our application there.
In both cases we have to do a little bit of setup work before we can finally see our application in action.
Before we can connect our device for testing purposes, we have to make sure that it is recognized by the operating system. On Windows, this involves installing an appropriate driver, which is part of the SDK installation we installed earlier. Just connect your device and follow the standard driver installation project for Windows, pointing the process to the driver/ folder in your SDK installation's root directory. For some devices, you might have to get the driver from the manufacturer's web site.
On Linux and Mac OS X, you usually don't need to install any drivers, as these come with the operating system. Depending on your Linux flavor, you might have to fiddle with your USB device discovery a little bit, usually in the form of creating a new rules file for udev. This varies from device to device. A quick web search should bring up a solution for your device.
The SDK comes with an emulator that will run so-called Android virtual devices (AVDs). A virtual device consists of a system image of a specific Android version, a skin, and a set of attributes, which include the screen resolution, SD-card size, and so on.
To create an AVD, you have to fire up the SDK and AVD manager. You can either do this as described previously in the SDK installation step, or directly from within Eclipse by clicking the SDK manager button in the toolbar.
1. Select Virtual Devices in the list on the left, and you will be presented with a list of currently available AVDs. Unless you've already messed around with the SDK manager, this list should be empty; let's change that.
2. To create a new AVD, click the New... button on the right, which will bring up the dialog shown in Figure 2-7.
Override the existing AVD with the same name
Figure 2-7. The AVD creation dialog of the SDK manager
3. Each AVD has a name by which you can refer to it later on. The target specifies the Android version that the AVD should use. Additionally, you can specify the size of the SD card of the AVD, as well as the screen size. For our simple Hello World project, you can select an Android 1.5 target and leave everything else as it is. For real-life testing, you'd usually want to create multiple AVDs that cover all the Android versions and screen sizes you want your application to handle.
NOTE: Unless you have dozens of different devices with different Android versions and screen sizes, it is advisable to use the emulator for additional testing of Android version/screen size combinations.
Now that you've set up your devices and AVDs, you can finally run the Hello World application. You can easily do this in Eclipse by right-clicking the "hello world" project in the Package Explorer view, and then selecting Run As > Android Application (or you can click the Run button on the toolbar). Eclipse will then perform the following steps for us in the background:
1. Compile the project to an APK file if any files have changed since the last compilation.
2. Create a new Run configuration for the Android project if one does not already exist. (We'll have a look into Run configurations in a minute.)
3. Install and run the application by starting or reusing an already running emulator instance with a fitting Android version, or by deploying and running the application on a connected device (which must also run at least the minimum Android version you specified as the Min SDK Level parameter when you created the project).
If you only created an Android 1.5 AVD, as suggested in the previous section, then the ADT Eclipse plug-in will fire up a new emulator instance running that AVD, deploy the Hello World APK file, and start the application. The output should look like Figure 2-8.
The emulator works almost exactly like a real device, and you can interact with it via your mouse just as you would with your finger on a device. Here are a few differences between a real device and the emulator:
■ The emulator only supports single-touch input. Simply use your mouse cursor and pretend it is your finger.
■ The emulator is missing some applications, such as the Android Market.
■ To change the orientation of the device on the screen, don't tilt your monitor! Instead, use the 7 key on your numpad to change it. For this, you have to first press the Num Lock key above the numpad to disable its number functionality.
■ The emulator is really, really slow. Do not assess the performance of your application by running it on the emulator.
■ The emulator currently only supports OpenGL ES 1.0 with a few extensions. We'll talk about OpenGL ES in Chapter 7. For our purposes this is fine, except that the OpenGL ES implementation on the emulator is buggy and will often give you different results from those you'll get on a real device. For now, just keep in mind that you should not test any OpenGL ES applications on the emulator.
Play around with it a little and get comfortable with it.
NOTE: Starting a fresh emulator instance takes considerable time (up to minutes depending on your hardware). You can leave the emulator running for your whole development session so you don't have to restart it over and over again.
Sometimes when we run an Android application, the automatic emulator/device selection performed by the ADT plug-in is a hindrance. For example, we might have multiple devices/emulators connected, and want to test our application on a specific device/emulator. To deal with this, we can turn off the automatic device/emulator selection in the Run configuration of the Android project. So, what is a Run configuration?
A Run configuration provides a way to tell Eclipse how it should start your application when you tell it to run it. A Run configuration usually allows you to specify things like command-line arguments passed to the application, VM arguments (in the case of Java SE desktop applications), and so on. Eclipse and third-party plug-ins offer different Run configurations for specific project types. The ADT plug-in adds an Android Application Run configuration to the set of available Run configurations. When we first ran our application earlier in the chapter, Eclipse and ADT created a new Android Application Run configuration for us in the background with default parameters.
To get to the Run configuration of your Android project, do the following:
1. Right-click the project in the Package Explorer view and select Run As > Run Configurations.
2. From the list on the left side, select the "hello world" project.
3. On the right side of the dialog, you can now modify the name of the Run configuration, and change other settings on the Android, Target, and Commons tabs.
4. To change automatic deployment to manual deployment, click the Target tab and select Manual.
When you run your application again, you'll be prompted to select a compatible emulator or device to run the application on. Figure 2-9 shows the dialog. In this figure, I added a couple more AVDs with different targets and also connected two devices.
Android Device Chooser
Select a device compatible with target Android 1.5. (*) Choose a running Android device
Serial Number emulator-5554 0 HT97JL901589 Q HT019P803783
AVD Name androidl.5
O Launch a new Android Virtual Device
Debug State Yes Online Online Online
O Launch a new Android Virtual Device
OK I I Cancel
Figure 2-9. Choosing an emulator/device to run the application on
The dialog shows all the running emulators and currently connected devices, as well as all other AVDs that are not running at the moment. You can choose any emulator or device to run your application on.
Debugging an Application
Sometimes our application will behave in unsuspected ways or crash. To figure out what exactly is going wrong, we want to be able to debug our application.
Eclipse and ADT provide us with incredibly powerful debugging facilities for Android applications. We can set breakpoints in our source code, inspect variables and the current stack trace, and so forth.
Before we can debug our application, we have to modify its AndroidManifest.xml file first to enable debugging. This presents a bit of a chicken-and-egg problem, as we haven't looked into manifest files in detail yet. For now, it suffices to know that the manifest file specifies some attributes of our application. One of those attributes is whether the application is debuggable. This attribute is specified in the form of an xml attribute of the <application> tag in the manifest file. To enable debugging, we add the following attribute to the <application> in the manifest file:
While developing your application, you can safely leave that attribute in the manifest file. But don't forget to remove it before you deploy your application to the market.
Now that you've set up your application to be debuggable, you can debug it on an emulator or device. Usually, you will set breakpoints before debugging to inspect the program state at certain points in the program.
To set a breakpoint, simply open the source file in Eclipse and double-click the gray area in front of the line you want to set the breakpoint at. For demonstration purposes, do that for line 23 in the HelloWorldActivity class. This will make the debugger stop each time you click the button. The source code view should show you a small circle in front of that line after you double-click, as in Figure 2-10. You can remove breakpoints by again double-clicking them in the source code view.
button. setText ("Touched rne "+touchCount+" tiine(s)"); Figure 2-10. Setting a breakpoint
Starting the debugging is much like running the application, as described in the previous section. Right-click the project in the Package Explorer view and select Debug As > Android Application. This will create a new Debug configuration for your project, just like in the case of simply running the application. You can change the default settings of that Debug configuration by choosing Debug As > Debug Configurations from the context menu.
NOTE: Instead of going through the context menu of the project in the Package Explorer view, you can use the Run menu to run and debug applications, as well as get access to the configurations.
If you start your first debugging session, Eclipse will ask you whether you want to switch to the Debug perspective, which you can happily confirm. Let's have a look at that perspective first. Figure 2-11 shows how it would look after starting debugging our Hello World application.
If you remember our quick tour of Eclipse, then you know that there are a couple of different perspectives, which consist of a set of views for a specific task. The Debug perspective looks a lot different from the Java perspective.
■ The first new view to notice is the Debug view at the top left. It shows all currently running applications and the stack traces of all their threads if they are run in debug mode.
■ Below the Debug view is the source-editing view we also used in the Java perspective.
■ The Console view prints out messages from the ADT plug-in, telling us what it is doing.
■ The LogCat view will be one of our best friends on our journey. It shows us logging output from the emulator/device that our application is running on. The logging output comes from system components, other applications, and our own application. It will show us a stack trace when our application crashes, and will also allow us to output our own logging messages at runtime. We'll have a closer look at LogCat in the next section.
■ The Outline view is not very useful in the Debug perspective. You will usually be concerned with breakpoints and variables, and the current line that the program is suspended at while debugging. I often remove the Outline view from the Debug perspective to leave more space for the other views.
■ The Variables view is especially useful for debugging purposes. When the debugger hits a breakpoint, we will be able to inspect and modify the variables in the current scope of the program.
■ Finally, the Breakpoints view shows a list of breakpoints we've set so far.
If you are curious, you've probably already clicked the button in the running application to see how the debugger reacts. It will stop at line 23, as we instructed it by setting a breakpoint there. You will also have noticed that the Variables view now shows the variables in the current scope, which consist of the activity itself (this) and the parameter of the method (v). You can further drill down into the variables by expanding them.
The Debug view shows us the stack trace of the current stack down to the method we are currently in. Note that you might have multiple threads running and can pause them at any time in the Debug view.
Finally, notice that the line where we set the breakpoint is highlighted, indicating the position in the code where the program is currently paused.
You can instruct the debugger to execute the current statement (by pressing F6), step into any methods that get called in the current method (by pressing F5), or continue the program execution normally (by pressing F8). Alternatively, you can use the items on the Run menu to achieve the same. Also notice that there are more stepping options than the ones I've just mentioned. As with everything, I suggest you experiment to see what works for you and what doesn't.
NOTE: Curiosity is a building block for successfully developing Android games. You have to get really intimate with your development environment to get the most out of it. A book of this scope can't possible explain all the nitty-gritty details of Eclipse, so again I urge you to experiment.
LogCat and DDMS
The ADT Eclipse plug-in installs many new views and perspectives to be used in Eclipse. One of the most useful views—already briefly touched on in the last section — is the LogCat view.
LogCat is the Android event-logging system, which allows system components and applications to output logging information of various logging levels. Each log entry is composed of a time stamp, a logging level, the process ID the log came from, a tag defined by the logging application itself, and the actual logging message.
The LogCat view gathers and displays this information from a connected emulator or device. Figure 2-12 shows some sample output from the LogCat view.
Figure 2-12. The LogCat view
Figure 2-12. The LogCat view
Notice that there are a number of buttons at the top right of the LogCat view.
■ The first five allow you to select the logging levels you want to see displayed.
■ The green plus button lets you define a filter based on the tag, the process ID, and the log level, which comes in handy if you want to show only the log output of your own application (which will probably use a specific tag for logging).
■ The rest of the buttons allow you to edit a filter, delete a filter, or clear the current output.
If several devices and emulators are currently connected, then the LogCat view will only output the logging data of one of these. To get finer-grained control and even more inspection options, you can switch to the DDMS perspective.
DDMS (Dalvik Debugging Monitor Server) provides a lot of in-depth information about the processes and Dalvik VMs running on all connected devices. You can switch to the DDMS perspective at any time via Window > Open Perspective > Other > DDMS. Figure 2-13 shows what the DDMS perspective usually looks like.
As always, there are a couple of specific views that are suitable for our task at hand. In this case, we want to gather information about all the processes, their VMs and threads, the current state of the heap, LogCat information about a specific connected device, and so on.
■ The Devices view displays all currently connected emulators and devices, as well as all the processes running on them. Via the toolbar buttons of this view, you can perform various actions, including debugging a selected process, recording heap and thread information, and taking a screenshot.
■ The LogCat view is the same as in the previous perspective, with the difference that it will display the output of the device currently selected in the Devices view.
■ The Emulator Control view lets you alter the behavior of a running emulator instance. You can force the emulator to spoof GPS coordinates for testing, for example.