Now, let's spend some time discussing applications—those things we write that provide value to the user. Android applications are made up of various types of classes and resources. The following sections describe the different types of classes or building blocks that an application can be composed of.
One of the most fundamental parts of an Android application is an activity. An activity provides a single function that a user can perform with an application such as list contacts, enter new contact, and display location(s) on a map. A single application is composed of many activities.
A user interacts with an activity through one or more Views, which are described later in this chapter. If you are familiar with the Model-View-Controller pattern, you would have noticed that activities fulfill the role of the Controller.
Activities have a well-defined life cycle that can be described in terms of states, transitions, and events. The following diagram provides a graphical view of the life cycle of an activity:
The states depicted in the previous diagram are derived, meaning there is no "State" variable on an activity that explicitly identifies one of these states, but the state is implied and useful for discussion. The following table describes the behavior of an activity based on its state:
During the transition between states, a series of events are called on the activity. These events provide developers a platform for various types of processing.
Something that is not obvious to developers new to Android is the way the framework deals with device orientation changes. By default, when the orientation of a device is changed from portrait to landscape, Android destroys and recreates existing activities to help ensure that the most appropriate layout is used. Unless this behavior is planned for, it can be very disruptive to processing. If needed, this behavior can be overridden and activities can be retained. We will discuss special considerations in dealing with state and other processing concerns related to this topic in Chapter 7, Making POIApp Location Aware.
Services are components that run in the background to perform long-running operations with no direct user interface. Services may load data into a cache, play music, or perform some other type of processing, while a user interacts with other activities uninterrupted.
Content providers manage access to a central repository of data such as contacts. A content provider is a part of an application, which usually provides a user interface to manage its data. A standard interface is also provided, which allows other applications to access its repository.
Broadcast receivers are components that perform some type of processing in response to system-wide broadcasts. Broadcasts are generally initiated by the system for events such as low battery, taking a picture, or turning on Bluetooth. Applications may also choose to send broadcasts; a content provider might send a broadcast when data, such as a contact, has been updated. While broadcast receivers do not have a user interface, they may indirectly cause updates to a status.
Everything that you see in an Android app is a View; buttons, labels, text boxes, and radio buttons are all examples of Views. Views are organized in a hierarchy using various types of ViewGroups. A ViewGroup is a special kind of View which is used to arrange (layout) other Views on the screen.
Views and ViewGroups can be created using two different methods, programmatically or declaratively. When using a programmatic approach, a developer makes API calls to create and position each individual View in the UI. When using a declarative approach, a developer creates XML layout files that specify how Views should be arranged. The declarative method enjoys several advantages stated as follows:
While I prefer the declarative method for most things, I have found that, in practice, some combination of programmatic and declarative methods are often required.
Android provides a comprehensive set of user interface widgets that can be used to build a rich user experience. All of these widgets are subtypes of View and can be organized into sophisticated layouts using various types of ViewGroups. All of the user interface widgets can be found in the android.widget
package within the Application Framework.
The Application Framework has a number of subclasses of ViewGroup
, each of which provides a unique and useful way of organizing content.
The previous diagram depicts a few of the more common layouts, each of which can be used for specific needs.
Layout |
Description |
Scenario |
---|---|---|
Organizes its children into a single horizontal or vertical row and creates a scrollbar when required. |
Use when a widget positions flow horizontally or vertically. | |
Organizes child objects relative to each other or to the parent. |
Use when widget positions can best be described in relationship to another widget (to the left of) or the boundary area of the parent (right side, centered). | |
Organizes its children into rows and columns. |
Use when widget positions would naturally fit into rows and columns. Great when multiple columns of entry and labels are needed. |
For complex layout scenarios, Android allows layouts to be nested. Deeply nested layouts can impact performance and should be avoided if possible.
To create a UI using a declarative method, Android provides an XML vocabulary with tags that define the various types of elements that can compose a View. The concept behind Android XML layout files is very similar to the way HTML tags are used to define web pages or Microsoft's XAML tags are used to define WPF (Windows Presentation Foundation) user interfaces. The following example shows a simple View using a linear layout and containing a search entry field and search button:
<?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:text="Enter Search Criteria" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/searchCriteriaTextView" /> <Button android:text="Search" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/searchButton" /> </LinearLayout>
Care has been taken to aligning the names for elements and attributes in the XML vocabulary with class and method names from the Application Framework. In the previous example, the element names LinearLayout
, TextView
, and Button
correspond to class names in the Application Framework. Likewise, in the Button element, the android:text
attribute corresponds to the setText()
setter on the
Button
class.
Each View can have a unique integer ID associated with it and can be used to reference the View from within an application's code. In the XML file, the ID is specified as a user friendly text name. For example, consider the following line of code:
android:id="@+id/searchButton"
In this example, the @
operator tells the parser that it should treat the remainder of the string as an ID resource; the +
symbol tells the parser that this is a new resource name that should be added to the resource file, R.java
. The resource file defines integer constants that can be used to reference resources.
Intents are messages that can be sent to the various types of components in an Android App in order to request some type of action to be performed. Intents may be used to accomplish any of the following:
Creating an Android application involves more than simply writing code. A rich mobile app requires things such as images, audio files, animations, menus, and style, just to name a few. The Application Framework provides APIs that can be used to load and utilize the various types of resources with your Android apps.
Downloading the example code
You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com . If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.
Resources are generally referenced from within an application using an integer constant that is automatically assigned when the resource is added to the project and compiled. These constants are placed in a Java source file named R.java
. The following example shows the R.java
class from a simple application:
public final class R { public static final class attr { } public static final class drawable { public static final int icon=0x7f020000; } public static final class id { public static final int myButton=0x7f050000; public static final int searchButton=0x7f050002; public static final int searchCriteriaTextView=0x7f050001; } public static final class layout { public static final int main=0x7f030000; public static final int search=0x7f030001; } public static final class string { public static final int app_name=0x7f040001; public static final int hello=0x7f040000; } }
18.118.253.123