The previous chapter stepped you through creating a stub project. This chapter describes what is inside of this project, so you understand what Android gives you at the outset and what the roles are for the various directories and files.
The Android build system is organized around a specific directory tree structure for your Android project, much like any other Java project. The specifics, though, are fairly unique to Android—the Android build tools do a few extra things to prepare the actual application that will run on the device or emulator. Here's a quick primer on the project structure, to help you make sense of it all, particularly for the sample code referenced in this book.
When you create a new Android project (e.g., via android create project
), you get several items in the project's root directory, including the following:
AndroidManifest.xml
: An XML file that describes the application being built and what components (activities, services, etc.) are being supplied by that applicationbin/
: The directory that holds the application once it is compiledlibs/
: The directory that holds any third-party JARs your application requiresres/
: The directory that holds resources, such as icons, GUI layouts, and the like, that are packaged with the compiled Java in the applicationsrc/
: The directory that holds the Java source code for the applicationIn addition to the preceding file and directories, you may find any of the following in Android projects:
assets/
: The directory that holds other static files that you want packaged with the application for deployment onto the devicegen/
: The directory in which Android's build tools place source code that they generatebuild.xml
and *.properties
: Files that are used as part of the Ant-based command-line build process, if you are not using Eclipseproguard.cfg
: A file that is used for integration with ProGuard to obfuscate your Android codeWhen you create an Android project (e.g., via android create project
), you supply the fully qualified class name of the main activity for the application (e.g., com.commonsware.android.SomeDemo
). You will then find that your project's src/
tree already has the namespace directory tree in place, plus a stub Activity
subclass representing your main activity (e.g., src/com/commonsware/android/SomeDemo.java
). You are welcome to modify this file and add others to the src/
tree as needed to implement your application.
The first time you compile the project (e.g., via ant
), out in the main activity's namespace directory, the Android build chain will create R.java
. This contains a number of constants tied to the various resources you placed in the res/
directory tree. You should not modify R.java
yourself, but instead let the Android tools handle it for you. You will see throughout this book that many of the examples reference things in R.java
(e.g., referring to a layout's identifier via R.layout.main
).
The res/
directory tree in your project holds resources—static files that are packaged along with your application, either in their original form or, occasionally, in a preprocessed form. Following are some of the subdirectories you will find or create under res/
:
res/drawable/
: For images (PNG, JPEG, etc.)res/layout/
: For XML-based UI layout specificationsres/menu/
: For XML-based menu specificationsres/raw/
: For general-purpose files (e.g., an audio clip or a CSV file of account information)res/values/
: For strings, dimensions, and the likeres/xml/
: For other general-purpose XML files you wish to shipSome of the directory names may have suffixes, like res/drawable-hdpi/
. This indicates that the directory of resources should be used only in certain circumstances—in this case, the drawable resources should be used only on devices with high-density screens.
We will cover all of these resources, and more, in later chapters of this book.
In your initial project, you will find the following:
res/drawable-hdpi/icon.png
, res/drawable-ldpi/icon.png
, and res/drawable-mdpi/icon.png
: Three renditions of a placeholder icon for your application for high-, low-, and medium-density screens, respectivelyres/layout/main.xml
: An XML file that describes the very simple layout of your user interfaceres/values/strings.xml
: An XML file that contains externalized strings, notably the placeholder name of your applicationWhen you compile your project (via ant
or the IDE), the results go into the bin/
directory under your project root, as follows:
bin/classes/
: Holds the compiled Java classesbin/classes.dex
: Holds the executable created from those compiled Java classesbin/yourapp.ap_
: Holds your application's resources, packaged as a ZIP file (where yourapp
is the name of your application)bin/yourapp-*.apk
: The actual Android application (where *
varies)The .apk
file is a ZIP archive containing the .dex
file, the compiled edition of your resources (resources.arsc
), any uncompiled resources (such as what you put in res/raw/
), and the AndroidManifest.xml
file. If you build a debug version of the application (which is the default), you will have yourapp-debug.apk
and yourapp-debug-aligned.apk
as two versions of your APK. The latter has been optimized with the zipalign
utility to make it run faster.
The foundation for any Android application is the manifest file, AndroidManifest.xml
, in the root of your project. This is where you declare what is inside your application—the activities, the services, and so on. You also indicate how these pieces attach themselves to the overall Android system; for example, you indicate which activity (or activities) should appear on the device's main menu (a.k.a., the launcher).
When you create your application, a starter manifest is generated for you automatically. For a simple application, offering a single activity and nothing else, the autogenerated manifest will probably work out fine, or perhaps require a few minor modifications. On the other end of the spectrum, the manifest file for the Android API demo suite is over 1,000 lines long. Your production Android applications will probably fall somewhere in the middle.
The root of all manifest files is, not surprisingly, a manifest
element:
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.commonsware.android.search">
...
</manifest>
Note the namespace declaration. Curiously, the generated manifests apply it only on the attributes, not the elements (e.g., manifest
, not android:manifest
). This pattern works, so, unless Android changes, you should stick with it.
The biggest piece of information you need to supply on the manifest
element is the package
attribute (also curiously not namespaced). Here, you can provide the name of the Java package that will be considered the “base” of your application. Then, everywhere else in the manifest file that needs a class name, you can just substitute a leading dot as shorthand for the package. For example, if you needed to refer to com.commonsware.android.search.Snicklefritz
in the preceding manifest, you could just use .Snicklefritz
, since com.commonsware.android.search
is defined as the application's package.
As noted in the previous chapter, your package also is a unique identifier for your application. A device can have only one application installed with a given package, and the Android Market will list only one project with a given package.
Your manifest also specifies android:versionName
and android:versionCode
attributes. These represent the versions of your application. The android:versionName
value is what the user will see in the Applications list in their Settings application. Also, the version name is used by the Android Market listing, if you are distributing your application that way. The version name can be any string value you want. The android:versionCode
value, on the other hand, must be an integer, and newer versions must have higher version codes than do older versions. Android and the Android Market will compare the version code of a new APK to the version code of an installed application to determine if the new APK is indeed an update. The typical approach is to start the version code at 1
and increment it with each production release of your application, though you can choose another convention if you wish.
TIP: The Android Market will present only one version (typically, the latest) of any APK. Should you ever want to deploy a different version and not have to go through the effort of recompiling from your code, you can take a backup of your APK for any given version and simply side-load it onto your device or emulator.
In your initial project's manifest, the only child of the <manifest>
element is an <application>
element. The children of the <application>
element represent the core of the manifest file.
One attribute of the <application>
element that you may need in select circumstances is the android:debuggable
attribute. This needs to be set to true
if you are installing the application on an actual device, you are using Eclipse (or another debugger), and your device precludes debugging without this flag. For example, the Google/HTC Nexus One requires android:debuggable = "true"
, according to some reports.
By default, when you create a new Android project, you get a single <activity>
element inside the <application>
element:
<?xml version="1.0"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.commonsware.android.skeleton">
<application>
<activity android:name=".Now" android:label="Now">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
This element supplies android:name
for the class implementing the activity, android:label
for the display name of the activity, and (frequently) an <intent-filter>
child element describing under what conditions this activity will be displayed. The stock <activity>
element sets up your activity to appear in the launcher, so users can choose to run it. As you'll see later in this book, you can have several activities in one project, if you so choose.