📌 Android is an operating system, like Windows and MacOS. Unlike those two systems, Android is a Linux-based OS, like Ubuntu and Red Hat. Unlike Ubuntu and Red Hat, though, Android has been very heavily optimized for mobile devices—battery-powered mobile devices, in particular.
The Android Stack
Hardware
- A piece of warm silicon. While the hardware is not part of the Android stack, it is important to recognize that the hardware for which Android was designed imposes some fairly tough constraints on the system. By far, the most significant of these constraints is power. Most common operating systems just assume an infinite power supply. The Android systems cannot.
Kernel
- The Android operating system depends on the Linux kernel.
- A kernel is responsible for providing the basic services that developers expect: a filesystem, threads and processes, network access, interfaces to hardware devices, and so on.
- Linux is free and open source and, thus, a popular choice for hardware and device manufacturers.
System Services
- The system services layer is big and complex.
- It includes a wide variety of utilities, from code that runs as part of the kernel (drivers or kernel modules), and long-running applications that manage various housekeeping tasks (daemons), to libraries that implement standard functions like cryptography and media presentation.
- This layer includes several system services that are unique to Android. Among them are Binder, Android’s essential interprocess communication system; ART, which has replaced Dalvik as Android’s analog of the Java VM; and Zygote, Android’s application container.
Android Runtime Environment (ART)
- ART and its predecessor Dalvik were originally created specifically for the Android project. ART as the runtime executes the Dalvik Executable format and Dex bytecode specification.
- The layer above the system services is the implementation of the Android Runtime Environment.
- The Android Runtime Environment is the collection of libraries that you use from your application by including them with
import
statements: android.view, android.os, and so on. They are the services provided by the layers below, made available to your application. They are interesting because they are implemented using two languages: usually Java and C or C++.
Applications
- The top of the stack are Android applications.
- Applications, in the Android universe, are actually part of the stack.
- They are made up of individually addressable components that other applications can “call.” The Dialer, Camera, and Contacts programs are all examples of Android applications that are used as services by other applications.
The Android Application Environment
- Android applications are programs translated from a source language (Java or Kotlin) into a transportable intermediate language, DEX.
- The DEX code is installed on a device and interpreted by the ART VM, when the application is run.
- Android apps are libraries of components. The Android runtime, Zygote, manages processes, lifecycles, and so on. It calls an application’s components only when it needs them.
- Component subclasses override the methods that are called by the framework in order to provide application-specific behavior.
- Often, the superclass has important work to do when one of these template methods is called. In those cases, the overriding method in the subclass must call the superclass method that it overrides.
- Android supports four types of components:
- Activity
- Service
- Broadcast receiver
- Content provider
- The implementations of these components must be registered in a manifest: AndroidManifest.xml.
Intents and Intent Filters
- An
Intent
is a small packet that names the component that it targets. - Components are started with
Intent
s. - An intent as a function call.
Kotlin
context.startActivity(
Intent(context, MembersListActivity::class.java)))
- This code fires an
Intent
at theActivity
MembersListActivity
. - The
Intent
fired by this line of code is called an explicit intent because it names a specific, unique class, in a unique application (identified by aContext
, discussed in a moment), to which theIntent
is to be delivered. - Imagine that the email application you’ve had on your phone for years allows editing messages with an external editor. We now can guess that it does this by firing an intent that might look something like this:
Kotlin
val intent = Intent(Intent.ACTION_EDIT))
intent.setDataAndType(textToEditUri, textMimeType);
startActivityForResult(intent, reqId);
- The target specified in this intention is not explicit. The
Intent
specifies neither aContext
nor the fully qualified name of a component within a context. The intent is implicit and Android will allow any component at all to register to handle it.
Context
- Because Android components are just subsystems run in a larger container, they need some way of referring to the container so that they can request services from it. From within a component, the container is visible as a
Contex
. Context
s come in a couple of flavors: component and application. Let’s have a look at each of them.
Component context
Kotlin
context.startActivity(
Intent(context, MembersListActivity::class.java)))
- This call uses a
Context
twice. First, starting anActivity
is a function that a component requests from the framework, theContext
. In this case, it called theContext
methodstartActivity
. Next, in order to make the intent explicit, the component must identify the unique package that contains the component it wants to start. TheIntent
’s constructor uses thecontext
passed as its first argument to get a unique name for the application to which thecontext
belongs: this call starts anActivity
that belongs to this application. - The
Context
is an abstract class that provides access to various resources, including:- Starting other components
- Accessing system services
- Accessing
SharedPreferences
, resources, and files.
Application context
- When Android starts an application, it usually creates a singleton instance of the
Application
class. That instance is aContext
and, though it has a lifecycle, that lifecycle is essentially congruent with the lifecycle of the application. Because it is long-lived, it is quite safe to hold references to it in other long-lived places.
XML
<manifest ...>
<application
android:name=".SafeApp"
...>
...
</application>
</manifest>
Android Application Components: The Building Blocks
The lifecycles of Android application components are managed by the Android framework, which creates and destroys them according to its needs.
The activity lifecycle
The activity lifecycle | Android Developers
An Activity is an application component that provides a screen with which users can interact in order to do something, such as dial the phone, take a photo, send an email, or view a map. Each activity is given a window in which to draw its user interface…
onCreate()
- Fires when the system first creates the activity.
- Basic application startup logic that should happen only once for the entire life of the activity.
onStart()
- Makes the activity visible to the user, as the app prepares for the activity to enter the foreground and become interactive.
- This method is where the app initializes the code that maintains the UI.
- The
onStart()
method completes very quickly and, as with the Created state, the activity does not stay resident in the Started state. - Once this callback finishes, the activity enters the Resumed state, and the system invokes the
onResume()
method.
onResume()
- When the activity enters the Resumed state, it comes to the foreground, and then the system invokes the
onResume()
callback. - This is the state in which the app interacts with the user.
- The app stays in this state until something happens to take focus away from the app.
- Such an event might be, for instance, receiving a phone call, the user’s navigating to another activity, or the device screen’s turning off.
onPause()
- The system calls this method as the first indication that the user is leaving your activity (though it does not always mean the activity is being destroyed); it indicates that the activity is no longer in the foreground (though it may still be visible if the user is in multi-window mode).
- Use the
onPause()
method to pause or adjust operations that should not continue (or should continue in moderation) while theActivity
- Paused activity may still be fully visible if in multi-window mode.
onStop()
- When your activity is no longer visible to the user, it has entered the Stopped state, and the system invokes the
onStop()
callback. - This may occur, for example, when a newly launched activity covers the entire screen. The system may also call
onStop()
when the activity has finished running, and is about to be terminated.
onDestroy()
onDestroy()
is called before the activity is destroyed. The system invokes this callback either because:- The activity is finishing (due to the user completely dismissing the activity or due to
finish()
being called on the activity), or- The system is temporarily destroying the activity due to a configuration change (such as device rotation or multi-window mode)
- The activity is finishing (due to the user completely dismissing the activity or due to
Fragments
Fragment
s are an afterthought added to Android’s stable of component-like features only at version 3 (Honeycomb, 2011).- They were introduced as a way of making it possible to share UI implementations across screens with shapes and sizes so different that it affects navigation: in particular, phones and tablets.
Fragment
s are notContext
s. Though they hold a reference to an underlyingActivity
for most of their lifecycleFragment
s are not registered in the manifest. They are instantiated in application code and cannot be started withIntent
s.Fragment
as something like an iframe on a web page: almost anActivity
embedded in anActivity
.
The back stack
- Android supports a navigation paradigm sometimes called card-deck navigation.
- Navigating to a new page stacks that page on top of the previous page.
- When a user presses a back button the current page is popped from the stack to reveal the one that previously held the screen.
- This paradigm is fairly intuitive for most human users: push new cards on top; pop them off to get back to where you were.
Services
- A
Service
is an Android component that is, almost exactly, anActivity
with no UI. That may sound a bit odd, given that anActivity
’s sole reason for existence is that it manages the UI! - Perform long-running tasks that are not attached to any UI: monitoring location, synchronizing a dataset over the network, and so on.
- There are two different kinds of
Service
: bound and started.
Content Providers
- REST-like interface to data held by an application. Because it is an API, not simply direct access to data, a
ContentProvider
can exercise very fine-grained control over what it publishes and to whom it publishes it. - External applications get access to a
ContentProvider
Broadcast Receivers
- The original concept for a
BroadcastReceiver
was as a kind of data bus. - Listeners could subscribe in order to get notification of events that were of interest.
- The most common use of a
BroadcastReceiver
is as a way of starting an application, even if there has been no user request to do so.