Chapter 4
Android SDK

4.1 Software Components, in general

There will be times when you hear the term “software component” applied to just any application class or object. Loosely speaking, the terms component, class, and object may be used interchangeably. However, there is a more specific, narrow definition and meaning of the term component that goes over and beyond a class or an object in the object-oriented paradigm.

Software components are typically characterized by strong interfaces, strong modularity, and strong separation of responsibilities between the application logic and the runtime “container” environment that houses components. The “container” is an environment that manages the full life cycle of the components that execute within it. The container is responsible for loading the component’s class, creating and destroying instances, pooling instances, injecting application and security contexts, enforcing security, providing and controlling access to resources and services, and so on. The motivation is to be able to create reusable building blocks and integrate them into a larger environment or system and achieve the goal of interoperability and seamless integration.

Whenever software is developed within a component-based development model, there is a greater emphasis on understanding the contractual obligations of the application developer versus the responsibilities of the runtime container provider.

Well-known component models include JavaBeans®, Enterprise JavaBeans®, Java Remote Method Invocation (RMI), Servlets®, Corba®, and so on. JavaBeans is one of the simplest and widely used components. JavaBeans strictly adhere to the well-defined contracts with respect to setters, getters, and constructors.

4.2 Android Application Development Model

Android application development involves a Java SDK-based development environment. Android developers use the Java programming language and the standard Sun Java JDK from Oracle in order to write Android application source code. However, the runtime ends up executing Dalvik Executable (DEX) code rather than Java bytecode.

There are many intermediate steps involved in compiling, building, and packaging an Android application. Firstly, the source code is compiled into Java class files via the Java JDK tools; after that, the Android SDK tools compile the Java class files into DEX files and package them into an Android application package (APK).

4.2.1 DEX file format

DEX is a bytecode format that is used to store executable code, and such bytecode is capable of being executed on an Android runtime virtual machine (VM). The DEX format is compact and was designed keeping resource constrained, small mobile devices in mind.

Whenever you build any Android project and browse through the intermediate files within the project’s directory tree, you will typically find a classes.dex file among the intermediate files. The classes.dex contains the application’s classes in DEX format.

Figure 4-1A shows such a classes.dex file that is typically found within any Android project’s home directory, after you have successfully built the project. The figure also shows the dexdump command, which is one of the Android SDK’s build tools and can be used to verify the checksum of a classes.dex file. You do not need to directly execute such build tools routinely, because your gradle, ant, or IDE-based build process takes care of this for you.

c4-fig-0001

Figure 4-1A classes.dex and dexdump.

4.2.2 APK file

The APK file is the artifact that is created or output from building your Android project, and it represents your application’s binary. It has the extension of .apk and is meant to be installed on your Android device. The .apk file is a zip-compatible archive that contains your application’s classes.dex file, AndroidManifest.xml file and resources, and binary content.

The Android application package (.apk) file has the Internet media-type identifier of:

  • application/vnd.android.package-archive

Each APK has exactly one package name associated with it. When you release your Android application to the Google Play Store, the package name serves as the ID for the application, and it is publicly visible as in the example below:

One of the latter steps in the process involves the signing of the Android APK using a keystore. While building your application in debug mode, the output APK typically has debug flags enabled, and it is signed by a debug keystore. While building applications in release (i.e., production) mode, the debug flags need to be turned off, and the APK will need to be signed using a release keystore. It is perfectly fine to use a self-signed certificate rather than a certificate from a certificate authority for the keystore.

When you release an application to the Google Play Store, all subsequent updates will need to be made by using the same keystore that was used originally. In case you lose the original keystore and password, you will not be able to release any updates to your application on the Google Play Store. It is therefore important to maintain your keystore carefully for future use.

It is recommended that released APKs be obfuscated. Obfuscation makes the code unfriendly toward reverse engineering while also making the code more compact. More information on obfuscation and Android application signing can be found at:

Also, there are particular requirements when publishing an application in the Google Play Store, details of which can be found at:

Figure 4-1B shows an example of the Android APK file that you will find within any Android project’s home directory, after you have successfully built the project. The figure shows two versions of the APK file, one that includes the term “unaligned” in its name. zipalign is an archive alignment and optimization tool that reduces the memory (RAM) consumed by the running application. zipalign is used in one of the last steps in the build process, and it is performed after application signing. zipalign is a build tool that is part of the Android SDK; it is typically used via the build process, rather than directly.

c4-fig-0002

Figure 4-1B Android apk file.

Besides the APK archive, there is the AAR archive, which is the output from building a library project or module that other Android application projects can depend on.

4.2.3 Android Project Build Process

A simplified version of the Android project build process is depicted in Figure 4-1C, and more details are available at https://developer.android.com/tools/building/index.html.

c4-fig-0003

Figure 4-1C Simplified view of Android application build process.

Attribution: Android Developer Documentation at developer.android.com.

4.2.4 APK installation and execution

When your App’s apk file is installed on an Android device, it is stored under an internal path such as /data/app/* on your device’s file system; the exact location is controlled by the Android OS. Due to security constraints implemented by Android, you generally cannot access or even list the installed APK files via the shell environment, using commands such as adb shell ls. The quickest way to reliably tell if a package (APK) has been installed is to use the package manager (pm) command: adb shell pm list packages -f. An installed package corresponds to an APK on a 1:1 basis. The snippet below shows the commands and outputs pertinent to determining if particular packages have been installed:

When your application is run on a device, it executes within its own isolated, secure sandbox. Android is at the low level an inherently multi-user system and runs each application in a VM process, under a distinct OS user ID that your application is unaware of, but internally the Android OS enforces security and permissions on the basis of this internal OS user ID. This helps keep the private files and data of each application separate and inaccessible from other Apps. The Android OS also ensures that the application accesses resources and functions that are consistent with the permissions that have been explicitly granted to the App by the user. Permissions are granted by the user at install time.

An application runs in a VM within a separate process, and it is isolated from other Apps—it cannot access the private content of other Apps, and in turn, other Apps cannot access its private content. The life cycle of the process is managed by the Android OS depending on the needs of the system.

The Android OS endeavors to enforce the principle of least privilege—Apps can access only the resources and features that are essential for performing work, consistent with the permissions that have been granted by the user and no more.

Although Apps live within their secure sandboxed environment, at the same time, there are mechanisms available that facilitate sharing of data between Apps. It is possible for an application to share data and content securely with another App or even be invoked from another App. Also, two Apps that have been signed by the same keystore/certificate (typically published by the same entity) can share the OS user ID—this is a very deep level of sharing because all files and content of one application are available to the other App, as though the two Apps were the same App.

4.2.4.1 Application main thread / UI thread

By default, all the components in an application run in the same OS process and thread called the “main thread” or “user interface (UI) thread.” When an application component needs to be started, if a process for the application already exists—because some other component of the same application is running—then Android utilizes that process and its main tread for executing the current component.

Long-running operations should be run in background threads rather than the main thread. In the interest of a good user experience, the Android system enforces application responsiveness by providing the user with an Application Not Responding (ANR) dialog whenever an application UI (Activity) performs lengthy operations on the main/UI thread and fails to respond to user input for more than 5 seconds. The ANR dialog allows the user to close and terminate such an application. In the case of BroadcastReceivers that are background components that engage the main thread of the application in order to handle system broadcast messages, the Android system enforces a 10 second timeout. More details on best practices related to ANR are available at http://developer.android.com/training/articles/perf-anr.html.

4.3 Android SDK API

The Android SDK reference is available at http://developer.android.com/reference/packages.html; Figure 4-2A shows a screenshot of a browser accessing the Android SDK reference documentation.

c4-fig-0004

Figure 4-2A Android API reference.

You will notice that there is an API level setting (toward the top left of the screen) that you can adjust depending on the API level that is of interest to you. API level 21, which corresponds to Android 5, is relevant for covering the material in this book.

In conjunction with this online API reference, the following resources will be highly useful in order to obtain an understanding of the Android platform:

4.3.1 Android Application Manifest (AndroidManifest.xml)

Every Android application must have a manifest file named AndroidManifest.xml. The manifest is a key artifact that contains all the metadata about the application including its package name, the target API level and the minimum API level, security permissions, the application’s constituent components, and much more: you may, for example, set your application to be debuggable during development or use the largeHeap flag to request Android to allocate a larger heap size for running your application. Detailed information on the Android manifest can be found in the Android Developer documentation at:

4.3.2 Android API package Overview

At the highest level of the Android package, you will encounter the namespaces android, dalvik, java, javax, and org. These high-level packages are shown in Figure 4-2B.

c4-fig-0005

Figure 4-2B Android API high level namespaces, sub-packages.

4.4 Android’s Four Fundamental Components

Android application development is based on a few key high-level components that constitute the building blocks of any Android application. These four fundamental components are the Activity, Service, BroadcastReceiver, and ContentProvider. Your application components that subclass these four high-level components (or any of their subclasses) must be declared in your Android application project’s manifest, that is, AndroidManifest.xml file. The life cycle of these components is managed by the Android runtime. This strong Android component model helps separate out the responsibilities of the Application container runtime environment and the application developer.

Figure 4-2C shows the Activity, Service, BroadcastReceiver, and ContentProvider classes that represent the fundamental Android application components. The Activity and Service classes implement several interfaces that have not been shown in this high-level diagram.

c4-fig-0006

Figure 4-2C Android fundamental components.

The Intent and Application classes have also been included in this diagram. The four core components are activated by “Intents.” Intents are fundamental to Android application development and runtime application execution. An Intent encapsulates an action to be performed and optionally also the data associated with the action. Intent Filters help components advertise the kinds of intents that they are capable of responding to. You will find “intent-filter” elements in the AndroidManifest.xml.

The Application class must be declared in the AndroidManifest.xml in order to be used. There is often no need to create a subclass of the Application class; however, if you choose to do so, it will need to be declared in the AndroidManifest.xml.

Activity, Service, and Application reside in the android.app package, while the BroadcastReceiver, ContentProvider, and Intent reside in the android.content package.

4.4.1 Android Project Artifacts

An Android project consists of the manifest (AndroidManifest.xml), java source files, and resources (res). Resources in turn include layouts, values, xml, raw, assets, and so on. It is recommended that strings be externalized and isolated from the application code. Also, the resource directories can have subdirectories for different form factors and screen resolutions. At runtime, the Android system matches the device’s form factor and screen resolution to the appropriate flavor of the resource available in your App. You can and will typically have different flavors of layouts, images, and text that the Android system can pick at runtime, depending on the device’s characteristics.

Android resources are an important and vast topic, and you will find useful information in the Android Developer guide at http://developer.android.com/guide/topics/resources/providing-resources.html.

4.5 Activity

The Activity is a UI component and represents a user’s interaction “activity” with the application. The Android system grants the Activity a window to display its UI within. Any given application has one or more Activities; typically, one Activity is marked in the manifest as a main Activity, which is the entry point into the application. Each Activity is intended to implement a particular user interaction and function. An Activity can start another Activity, and then terminate itself or not, depending on the application’s flow and needs. The life cycle of the Activity is completely managed by the Android system. The application code should never instantiate an Activity; furthermore, it should never pass an Activity’s this reference to any component whose life cycle is not a slave to that Activity’s life cycle. The layout of the Activity’s UI is typically externalized as an xml resource file, and is located under the res/layout tree:

Running and previously running Activities are organized as a stack, with one Activity that is in the foreground and interacting with the user, at the top of this Activity stack. A task is a collection of such Activities, and the order in which the Activities were run determines their place in the stack. The device home screen is the starting point of most tasks.

Figure 4-2D shows the Activity stack, which you can access by touching the square, recent Apps button on Android 5 devices.

c4-fig-0007

Figure 4-2D Activity stack.

Figure 4-3A shows only a minuscule subset of the operations that are available in the Activity class. The setContentView method sets the Activity’s content to a view that is typically the compiled equivalent of the xml layout—as shown in the snippet below:

c4-fig-0008

Figure 4-3A Activity class, partial listing.

The call to setContentView is typically made in the onCreate method, which is a life cycle callback method that is called when an Activity is created. The Activity life cycle and callbacks are covered in the next section. An Activity can terminate itself by calling the finish method.

4.5.1 Activity life cycle

The Activity has a specific life cycle and can exist at any given time, in one of three given states:

Resumed/Running—The entire Activity is visible in a full screen and has focus. The Activity has already been created and started and is running in the foreground of the screen. It is at the top of the Activity stack.

Paused—The Activity has lost focus but is still visible, as it is partially obscured by some other UI. The Activity is still alive in that its state and member variables are still intact and it continues to remain attached to the window manager.

Stopped—The Activity is no longer visible, as it is completely obscured by some other UI. It continues to retain its state and member variables; however, it is no longer connected to the window manager.

When an Activity is in a paused or stopped state, the Android system may kill its process or finish off the Activity in order to reclaim OS system resources. When such an Activity needs to be displayed to the user again, it will need to be restarted, and the application code will need to ensure that the previous state is restored. SharedPreferences is a mechanism via which an application can store key–value pairs related to the state. More information on SharedPreferences, as well as data storage in general, is available at:

Figure 4-3B shows a diagram from the Android developer site that shows Activity states as well as the callback methods that you may implement according to the needs of your application’s Activity.

c4-fig-0009

Figure 4-3B Activity life cycle.

Attribution: Android Developer Documentation at developer.android.com.

The onCreate method is called when your Activity is created. You will typically need to override the onCreate method. It is recommended to call super.onCreate first before implementing any of your Activity’s initialization code that generally includes a call to setContentView to set the Activity’s content to a layout that defines the UI. The onCreate and onDestroy methods are the callback hooks into the entire lifetime of the Activity. Any global resources initialized in the onCreate should ideally be released in the onDestroy method.

Similarly, the onStart and the onStop methods represent the callback hooks into the visible lifetime of the Activity. The Activity’s visible lifetime includes the foreground lifetime and the partially visible (paused period) of the Activity. If you register a listener of some sort in your onStart method, you would ideally unregister it in your onStop method.

The onResume and onPause methods represent the foreground lifetime of an Activity. Because the Activity can go frequently between the paused and resumed states, these methods will tend to be called frequently, and the code in these callback methods is generally lightweight.

One simple, effective way to see your the Activity’s life cycle callbacks in action is to write a simple Activity and include logging in all the callback method implementations. The documentation on the android.util.Log class is available at http://developer.android.com/reference/android/util/Log.html. Once you have installed your application to a device, you can watch the logs as you change the orientation of the device or even simply let it “rest” until the screen fades or locks due to the idle timeout. You will likely find that there are a lot more Activity life cycle callbacks occurring than you might have expected. Mastering the Activity life cycle is one of the foundations of Android application development.

Any Android application runs in one or more OS processes. The OS processes too have their own life cycle, the details of which are available at:

While the Activity is a widely used fundamental UI component, you will typically use Activities in conjunction with Fragments. Fragments are modular, reusable UI subcomponents that are embedded within Activities. The life cycle of a Fragment is a slave to the life cycle of its containing Activity. The following are useful references on Fragments:

4.6 Service

A Service is a non-UI component that can perform operations in the background. For example, an Activity may start a service to offload potentially long-running operations such as network calls or file I/O to a service. Services may be bound or unbound. In the case of a bound service, other components such as an Activity can invoke method calls on the service’s interface after binding to the service. The service interface can be implemented via AIDL, in which case the service can be called both from external applications and by components within the same application. There are a cost and an overhead with implementing the service interface via AIDL.

Figure 4-4 shows a few of the attributes and methods available in the Service class. The onCreate method is a callback that is called by the Android system, when the service is first created. The onStartCommand is called by the Android system, every time that a component such as an Activity invokes the Context.startService method using an Intent that is associated with the Service. The onStartCommand returns to the Android system, an int value that indicates to the Android system how it should manage the behavior of the Service if its process gets killed. The constant START_STICKY is one of several possible values that are meant to be returned by the onStartCommand to indicate to the Android system how the service is to be managed. Particularly, if START_STICKY is returned by onStartCommand and the process is killed after the service was started, the Android system will try to create the Service again. This mode is useful for long-running background Services, such as music playback. If there were any resources that were created or initialized in the onCreate method, the same resources should typically be released in the onDestroy callback method.

c4-fig-0010

Figure 4-4 Service.

A Service can be started by calling Context.startService or Context.bindService. The Context.startService requires an explicit Intent, starting with Android 5. Use of intent filters is not recommended. Intents and Intent Filters have been covered later in this chapter.

The Service class itself is not threaded; nor is it inherently a separate process. By default, it runs in the same process as the rest of the application that it belongs to. The Service thus runs in the main thread of its containing process, and you will need to implement a separate thread in the application logic in order to perform long-running work in order to avoid the risk of an ANR situation.

Your service class must be declared in the manifest within the <service> element, and the syntax for this is as follows:

The exported flag attribute governs whether the service can be invoked by external applications.

Detailed information on services and service element is available at:

4.7 BroadcastReceiver

A BroadcastReceiver is a component that can consume a system-wide broadcast message, and it does so via its onReceive handler method (Figure 4-5). Your application’s broadcast receiver component will need to extend BroadcastReceiver and override the onReceive method. The nature of the broadcast is asynchronous, and its consumption is executed in the background. However, the Android system considers your application BroadcastReceiver instance to be active for the duration of execution of the onReceive method, subject to a maximum of 10 seconds.

c4-fig-0011

Figure 4-5 BroadcastReceiver.

Using a LocalBroadcastManager is preferable, as it entails less overhead and increases security as data will never leave your application when using a local broadcast.

4.8 ContentProvider

ContentProviders are a particular mechanism for storing application data on the Android device (Figure 4-6).

c4-fig-0012

Figure 4-6 ContentProvider.

Most Android applications need to persist application data. At the very least, they may need to save some settings or application state so as not to lose data when the application is paused. SharedPreferences are useful for storing key–value pairs, while files can be used to store arbitrary data. Android includes the SQLite database for storing structured data and retrieving structured data. ContentProviders help abstract out the underlying mechanism of storage and support sharing of data between applications while enforcing security constraints on the data access. The Android API provides off-the-shelf content providers for calendars, contacts, and media files. You may choose to implement your own content provider, especially if sharing of the content is relevant. Other advantages of ContentProviders are that they work well with Sync Adapters (which are useful for keeping content in sync between device storage and cloud-based storage) and search suggestions. More details on the general background about Android data persistence, ContentProviders, and Sync Adapters can be found at:

4.9 Intent

The Intent is a very powerful and important construct that is fundamental to Android application development and runtime execution. An Intent represents a conceptual definition of an action or operation that needs to be performed. Intents are involved even before the most trivial application can be started on your device.

Although the Intent is merely a passive message or data structure, it is used by the Android platform as a late binding mechanism between different components, which is why an Intent is so powerful. Intents can be used by one component to start another component within the same application or even in a different application. Intents are also used to receive broadcasts either via declaration in the manifest or via the Context.registerReceiver method. Intents are intercepted and handled by the Android system at runtime.

In the real world, you may have the intention of lighting up your room, and you may achieve this by flipping on a light switch. There may be more than one switch in the room, or you may even have other mechanisms for turning on the lights (such as via using a smart phone or wearable application to turn a Bluetooth lamp). On the one hand, you have a conceptual action, and on the other hand, you have one or more concrete mechanisms available for invoking that action. Android Intents provide a similar separation of the abstract action from the concrete component that is to be started via “implicit” Intents—which we will be covering shortly.

The Intent class resides in the android.content package. The primary attributes of the Intent are the action (or component’s class name) and the associated data, while the secondary attributes include categories, MIME type of the data and extras. The component’s class name can act as a secondary attribute when used in conjunction with other attributes. In many instances, setting the component name (fully qualified package and class name) of the component to be started is adequate information for proceeding further. When the action name (String) is specified and no component name has been specified, the Android system attempts to resolve the action to a matching component based on all the applications that have been installed on the user’s device. The intent filter in the application’s manifest declares the Intent actions that a given component has interest in being associated with.

You may have intents that handle custom actions that are not from among the numerous generic actions that are predefined as static constants in the Intent class. The Intent namespace is global so in case you define your own Intent, it is important to ensure uniqueness by using your application’s package name as a prefix to the action’s name.

The Intent class has several constructors including an empty constructor. Such an empty Intent will certainly need some attributes to be set—such as an action, component, and possibly data—before it can be meaningfully used. Other available constructors allow you to set the action and/or the component class details in one step while instantiating the Intent. Extras can be set on the Intent using the overloaded putExtra method. There are a large number of overloaded versions of the putExtra method to cater to different fundamental and commonly used data types.

Figure 4-7 shows some only a subset of the attributes and methods available in the Intent class in order to provide a conceptual understanding of the Intent class. The complete details of are available in the API reference: http://developer.android.com/reference/android/content/Intent.html.

c4-fig-0013

Figure 4-7 Intent class diagram, partial listing.

There are several static final attributes available in the Intent that help define various types of information:

  • Standard Activity Actions —These are numerous standard actions associated with Activities, and only a few have been shown in the diagram such as ACTION_VIEW, ACTION_DIAL, and ACTION_MAIN. Depending on the particular action, additional data may be required. For instance, ACTION_DIAL requires associated phone number data as a uniform resource identifier (URI) (Tel.: 6502752515), which can be parsed using Uri.parse. We will be covering standard activity actions in detail shortly, in the section on Implicit Intents.
  • Standard Broadcast Actions —These are standard actions associated with broadcasts, which BroadcastReceivers can register for, in order to receive broadcasts. The Intent action ACTION_BOOT_COMPLETED, for example, represents the completion of the boot process, when your device boots up. In order to implement a BroadcastReceiver that has interest in receiving this broadcast intent, you will need to declare the android.permission.RECEIVE_BOOT_COMPLETED in the application’s manifest file.
  • Standard Categories —These are secondary attributes that can be associated with Intents. CATEGORY_LAUNCHER is one such example of a standard category. CATEGORY_LAUNCHER is used along with ACTION_MAIN in the intent filter of your main Activity in your application’s manifest—they help declare that the particular (main) Activity is the entry point of your application and its icon and label are to be displayed in the application launcher:
  • Standard Extras —These are secondary attributes associated with Intent actions that can be set on and accessed from the Intent instance. Several EXTRA_* attributes have been defined such as EXTRA_EMAIL, EXTRA_SUBJECT, and EXTRA_CC, which are pertinent to sending an email via a standard Activity action ACTION_SEND. Extras are key–value pairs that are secondary to the Intent data. The Intent data is defined via an URI (governed by RFC 2396; https://www.ietf.org/rfc/rfc2396.txt).
  • Flags —These are secondary attributes that can be set on Intents, which influence how the Intent is handled by the Android system. Several FLAG_* attributes have been defined as static final constants.

4.9.1 Intent Action and Data

The Intent as we just covered encapsulates an action and optionally some associated data. The Intent action ACTION_VIEW is one of the generic intent actions defined as a static constant in the Intent class. It has the String value of android.intent.action.VIEW. The Intent ACTION_VIEW must have associated data, in order for it to be meaningful.

As mentioned earlier, the ACTION_DIAL requires the phone number data, in the format “Tel.: 6502752515.” The intent’s data needs to be set via the setData method. The prefix “Tel.:” is important in order to work with the Uri.parse method. The ACTION_DIAL only displays the phone number in a dialer program and does not actually make the call without the user’s subsequent action. A related intent ACTION_CALL initiates the phone call directly using the phone number data provided; it requires a permission android.permission.CALL_PHONE. Thus, the action and data go together when working with Intents. The action in conjunction with the data and its MIME type governs how the Android system resolves the (implicit) intent.

4.9.1.1 Intent Extras

An Extra is a Bundle of additional information that can be used to deliver information to the component that is being started via the Intent. As mentioned in an earlier section, the ACTION_SEND in conjunction with the extras EXTRA_EMAIL and EXTRA_SUBJECT can be used to send an email. Such standard extras help interoperability across Apps. When you use an Intent to start a component within your own application, you will typically use your application’s static final String constants “EXTRA_SOMETHING” rather than the standard extras.

4.9.1.2 Intent Flags

Intent Flags are secondary Intent attributes that influence the behavior of the component that is called via the Intent. The FLAG_ACTIVITY_* family of flags pertain to the behavior of Activities that are launched via Intents via the Context.startActivity method, while the FLAG_RECEIVER_* family of flags pertain to the Context.sendBroadcast method call.

As an example, if the FLAG_ACTIVITY_CLEAR_TOP is set on the Intent that is used to start an Activity, a new instance is not launched if that Activity already happens to be running in the current task; rather, the existing Activity will be brought to the forefront and the Intent delivered to it. There are other flags available that facilitate various contrasting flavors of Activity behavior.

4.9.2 Explicit Intents

When you create an Intent without providing/setting any action and explicitly set a fully qualified class name of the component that you would like to start or invoke, that is an explicit Intent. The fully qualified class name of the component can be specified via the Intent’s constructor parameter or via subsequently calling the setter method on the Intent instance.

Typically, you use explicit intents to start other components within the same App. It is very common for one Activity to may start another Activity or a Service within the same application, and explicit Intents are the ideal way to accomplish this.

The explicit Intent is not a separate class in the API—depending on the specifics of how the Intent is constructed and set up, and particularly if a component or class is set on the Intent instance explicitly while excluding an action, the intent is considered to be an explicit intent.

Explicit intents are more secure and you should always use an explicit intent when starting services. Android 5 (API level 21) enforces this principle by throwing an exception in case you call bindService without an associated explicit intent.

4.9.3 Implicit Intents

When you create an Intent and associate it with an action (String), typically without specifying the fully qualified class name of the component that you would like to start or invoke, that is an implicit Intent. The action can be specified via the Intent’s constructor parameter or via subsequently calling the setter method on the Intent instance.

Implicit Intents are usually used in conjunction with the standard generic actions that have been defined as static constants in the Intent class. ACTION_VIEW (android.intent.action.VIEW) and ACTION_DIAL (android.intent.action.DIAL) are two such standard actions that are widely used with Implicit Intents.

4.9.4 Intent Filter

The Android system matches an implicit Intent to identify and target the corresponding component that needs to be started. One very widely used intent is the ACTION_MAIN (with the category of CATEGORY_LAUNCHER), which the Android system uses to find all the main activities of all the Apps installed on the device to populate the application launcher with their names and icons.

You will find that the most trivial of the Android apps that you have written so far including our “Hello Lollipop” series in the last chapter has an intent-filter element in the application manifest (AndroidManifest.xml) that resembles the following snippet:

Intents and Intent Filters work closely together. The concept of Intent Filters, the intent-filter element in the manifest, and the class IntentFilter are topics for further reading at the links provided below:

4.9.5 Intent Resolution

The Android system matches an implicit Intent to the component (Activity) that needs to be started. This process is referred to as Intent Resolution. The Android system filters and resolves intents based on the encapsulated action and the associated data and categories. The data itself consists of the type, scheme, authority, and path.

It is possible that no component matching the implicit intent can be found (based on what Apps the user has installed on their device), and this can cause a crash. In order to avoid the crash, you must first ensure that a matching component exists by calling the method resolveActivity on the Intent, before calling startActivity.

It is also possible that more than one matching component is found. The Android system provides the user with the ability to choose the appropriate application (such as the choice of browsers that match the ACTION_VIEW on a Web URL data). The createChooser method and the ACTION_CHOOSER are associated with providing the calling application the option to display an alternative application/activity chooser with a customized title, upon multiple matching components for the Intent.

4.9.6 Intent Use Cases

The following is a summarization and listing of the ways in which Intents can be used.

4.9.6.1 Starting Activities

An Activity can be started using an Intent by calling the startActivity method available in Context. Data and extras may be set on the Intent. In the case of an explicit Intent, the Intent encapsulates the name of the Activity class that needs to be started. In the case of an implicit Intent, the Android system resolves the intent based on its encapsulated attributes to a matching component or components.

4.9.6.2 Starting Services

A Service can be started using an Intent via the startService method available in the Context. Only explicit Intents are to be used in order to start Services.

4.9.6.3 Delivering Broadcasts

Intents can be used to send broadcasts using the sendBroadcast method available in the Context. Such a broadcast can be sent within the same application of between applications. The LocalBroadcastManager is recommended for sending broadcasts within the same process.

4.10 android package, sub-packages

The purpose of this section is to provide a bird’s-eye view of the Android SDK’s high-level packages. The vast majority of the Android SDK’s classes and interfaces reside in subpackages under the android namespace. There are two classes that reside directly in the android package, namely, Manifest and R. The Manifest class has a nested class Manifest.permission that defines various permissions, and these permissions are universally used via the AndroidManifest.xml. The R class represents the global resources available to any Android App. Typically, Apps use resources from the R class that is available within their Apps package namespace. Apps can use some resources from the global R class, though drawable resources should be avoided. Resources from the global R class, if used in your application, can cause version dependencies and incompatibilities in your App, so they are best avoided. If you inadvertently import android.R into any of your application classes, that can cause the references to your own application’s R attributes to become unresolvable. More information on the subject of resources is available at:

Figure 4-8 shows the sub-packages within the android namespace.

c4-fig-0014

Figure 4-8 android sub-package, partial listing.

4.11 dalvik package, sub-packages

The sub-packages and classes under the dalvik namespace represent low-level functionality that is seldom used in applications. Yet, they have been included here to emphasize that the deeper system-level functionality is centered around “dalvik.”

Figure 4-9 shows the sub-packages within the dalvik namespace.

c4-fig-0015

Figure 4-9 dalvik sub-package.

4.12 java and javax package, sub-packages

The java sub-packages are familiar to Java developers and resemble the Java Standard Edition that has been brought into the Android platform from Apache Harmony project. The artifacts in this namespace “java” have variations and exclusions—particularly the Java Swing® API classes have been excluded. The security and cryptographic APIs under java.* and javax.* leverage Bouncy Castle and OpenSSL. When you are writing your Android application, it is important to be guided by the API reference documentation at

4.13 org package, sub-packages

The org namespace contains several external projects such as the apache http client, parsers for json, and xml.

Figure 4-10 shows the sub-packages such as apache, json, xml, and so on.

c4-fig-0016

Figure 4-10 org sub-package.

4.14 Sample code in this book

The source code for this book is organized into three top level directories:

  • lollipop
  • wear
  • fit

The source code under lollipop covers the base Android platform and has the following project subdirectories:

  • 0hellol 1hellol 2hellostudio 3ui 4alarm 5services 6provider 7maps 8notifications

Each project has a README file with relevant build instructions.

References and Further Reading

  1. http://en.wikipedia.org/wiki/Component-based_software_engineering#Software_component
  2. http://en.wikipedia.org/wiki/Java_servlet
  3. http://en.wikipedia.org/wiki/Common_Object_Request_Broker_Architecture
  4. http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138781.html
  5. http://en.wikipedia.org/wiki/JavaBeans
  6. https://source.android.com/devices/tech/dalvik/dex-format.html
  7. http://en.wikipedia.org/wiki/Internet_media_type
  8. https://developer.android.com/tools/building/index.html
  9. http://developer.android.com/tools/help/proguard.html
  10. http://developer.android.com/tools/publishing/app-signing.html
  11. http://proguard.sourceforge.net/
  12. http://developer.android.com/tools/publishing/app-signing.html
  13. http://developer.android.com/reference/packages.html
  14. http://developer.android.com/training/index.html
  15. http://developer.android.com/training/articles/perf-anr.html
  16. http://en.wikipedia.org/wiki/Bouncy_Castle_%28cryptography%29
  17. https://www.bouncycastle.org/
  18. http://en.wikipedia.org/wiki/OpenSSL
  19. https://www.ietf.org/rfc/rfc2396.txt
  20. http://developer.android.com/guide/components/services.html
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.114.125