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:
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 the 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 website. Many devices can use the Android ADB drivers that come with the SDK; however, a process is often required to add the specific device hardware ID to the INF file. A quick Google search for the device name and “Windows ADB” will often get you the information you need to get connected with that specific device.
On Linux and Mac OS X, you usually don't need to install any drivers, as they 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 do this either as described previously in the SDK installation step or directly from within Eclipse by clicking the SDK manager button in the toolbar.
Figure 2–7. The AVD creation dialog for the SDK manager
NOTE: Unless you have dozens of different devices with different Android versions and screen sizes, you should 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 in the background:
If you created only 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:
Play around with it a little and get comfortable.
NOTE: Starting a fresh emulator instance takes considerable time (up to 10 minutes depending on your hardware). You can leave the emulator running for your whole development session so you don't have to restart it repeatedly, or you can check the "Snapshot" option when creating or editing the AVD, which will allow you to save and restore a snapshot of the VM, allowing for quick launch.
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 we 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 Eclipse to run the application. A Run configuration usually allows you to specify things such as 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 types of project s. 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:
When you run your application again, you'll be prompted to select a compatible emulator or device on which to run the application. Figure 2–9 shows the dialog. In this figure, we added several AVDs with different targets and connected two devices.
The dialog shows all the running emulators and currently connected devices as well as all other AVDs not currently running. You can choose any emulator or device on which to run your application.
Sometimes your application will behave in unexpected ways or crash. To figure out what exactly is going wrong, you want to be able to debug your 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 to enable debugging. This presents a bit of a chicken-and-egg problem, as we haven't looked at manifest files in detail yet. For now, you should know simply that the manifest file specifies some attributes of your 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:
android:debuggable="true"
While developing your application, you can safely leave that attribute in the manifest file. But don't forget to remove the attribute before you deploy your application in 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 at which you want to set the breakpoint. 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 it, as shown in Figure 2–10. You can remove breakpoints by double-clicking them again in the Source Code view.
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 as 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 whether you want to switch to the Debug perspective, which you can confirm. Let's have a look at that perspective first. Figure 2–11 shows how it would look after we start debugging our Hello World
application.
If you remember our quick tour of Eclipse, then you'll know there are several different perspectives, which consist of a set of views for a specific task. The Debug perspective looks quite different from the Java perspective.
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 drill down further into the variables by expanding them.
The Debug view shows you the stack trace of the current stack down to the method you are in currently. 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. In addition, notice that there are more stepping options than the ones we've just mentioned. As with everything, we 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 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 we urge you to experiment.
The ADT Eclipse plug-in installs many new views and perspectives to be used in Eclipse. One of the most useful views is the LogCat view, which we touched on briefly in the last section.
LogCat is the Android event-logging system that allows system components and applications to output logging information about various logging levels. Each log entry is composed of a time stamp, a logging level, the process ID from which the log came, 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.
Notice that there are a number of buttons at the top right of the LogCat view.
If several devices and emulators are currently connected, then the LogCat view will output the logging data of only one. 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, several specific views 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.
Figure 2–13. DDMS in action
DDMS is actually a standalone tool integrated with Eclipse via the ADT plug-in. You can also start DDMS as a standalone application from the $ANDROID_HOME/tools
directory(%ANDROID_HOME%/tools
on Windows). DDMS does not directly connect to devices, but uses the Android Debug Bridge (ADB), another tool included in the SDK. Let's have a look at ADB to round off your knowledge about the Android development environment.
ADB lets you manage connected devices and emulator instances. It is actually a composite of three components:
adb
(which should work if you set up your environment variables as described earlier). When we talk about ADB, we refer to this command-line program.Usually, we use ADB via DDMS transparently and ignore its existence as a command-line tool. Sometimes ADB can come in handy for small tasks, so let's quickly go over some of its functionality.
NOTE: Check out the ADB documentation on the Android Developers site at http://developer.android.com
for a full reference list of the available commands.
A very useful task to perform with ADB is to query for all devices and emulators connected to the ADB server (and hence your development machine). To do this, execute the following command on the command line (note that > is not part of the command).
< adb devices
This will print a list of all connected devices and emulators with their respective serial numbers, and it will resemble the following output:
List of devices attached
HT97JL901589 device
HT019P803783 device
The serial number of a device or emulator is used to target specific subsequent commands at it. The following command will install an APK file called myapp.apk
located on the development machine on the device with the serial number HT019P803783
.
> adb –s HT019P803783 install myapp.apk
The –s
argument can be used with any ADB command that performs an action that is targeted at a specific device.
Commands that will copy files to and from the device or emulator also exist. The following command copies a local file called myfile.txt
to the SD card of a device with the serial number HT019P803783
.
> adb –s HT019P803783 push myfile.txt /sdcard/myfile.txt
To pull a file called myfile.txt
from the SD card, you could issue the following command:
> abd pull /sdcard/myfile.txt myfile.txt
If there's only a single device or emulator currently connected to the ADB server, you can omit the serial number. The adb
tool will automatically target the connected device or emulator for you.
Of course, the ADB tool offers many more possibilities. Most are exposed through DDMS, and we'll usually use that instead of going to the command line. For quick tasks, though, the command-line tool is ideal.