What makes up an Android project
Overview of Android components
The manifest file
Intents
Now that we know our way around Android Studio, let’s look closer at the structure of an Android app.
What Makes Up an Android Project
The app in Figure 5-1 is a big one—it’s got everything in it. Your app doesn’t have to be as big. You don’t need to put all kinds of components in your app, just build what you need; but it’s worth our while to learn about all of the components (some more than others), especially the basic ones like Activities and Intents.
APK is short for Application Package Kit. It’s the package file format that Android uses to distribute and install applications. If Windows apps are packaged either via EXE or MSI and macOS apps use DMG, Android uses APK.
Activities, Services, BroadcastReceivers, and ContentProviders are called Android components. They are the key building blocks of an application. They are high-level abstractions of useful things like showing a screen to a user, running a task in the background, and broadcasting an event so that interested applications may respond to them. Components are precoded or prebuilt classes with very specific behavior, and we use them by extending them so we can add the behavior that’s unique to our application.
Building an Android app is a lot like building a house. Some people build houses the traditional way—they assemble beams, struts, floor panels, and so on. They build the doors and other fittings from raw materials by hand, like an artisan. If we build Android applications this way, it might take us a long time, and it also might be quite difficult. The skill necessary to build applications from scratch could be out of reach for some programmers. In Android, applications are built using components. Think of components like prefabricated pieces of a house; the parts are manufactured in advance, and all they require is assembly.
An Activity is where we put together things that the user can see. It’s a focused thing that a user can do. For example, an Activity can be made so a user can view a single email or maybe fill up a form. In Figure 5-1, inside the Activity, there are Views and Fragments. Views are classes that draw content to the screen; some examples of View objects are Buttons and TextViews. A Fragment is similar to an Activity in a way that it’s also a composition unit but a smaller one. Like Activities, they also hold View objects. Some apps use Fragments to address the problem of deploying them on multiple form factors—Fragments can be turned on or off depending on the available screen space and/or orientation.
Services. With Services, we can run program logic behind the scenes, without freezing the user interface. Services run in the background; they can be very useful when your app is supposed to download a file from the Web or maybe play music.
BroadcastReceivers. With BroadcastReceivers, our app can listen to messages from other applications or from the Android Runtime itself; a sample use case for this might be if you want to display a warning message when the battery dips to below 10%.
ContentProviders lets you write apps that can share data to other apps without exposing the underbellies of your apps’ SQL structure. It manages access to some sort of central data repository. The details of database access are completely hidden from other apps. An example of a prebuilt application that is a ContentProvider is the “Contacts” app in Android.
Your application may need some visual or audio assets; these are the kinds of things we mean by “Resources” in Figure 5-1.
The name of the app.
Which Activity will show up first when the user launches the app.
What kind of components are in the app. If it has activities, the manifest declares them—names of classes and all. If the app has services, their class names will also be declared in manifest.
What kinds of things can the app do? What are its permissions? Is it allowed to access the Internet or the camera? Can it record GPS locations and so on?
Does it use external libraries?
What version(s) of Android will this app run on?
Does it support a specific type of input device?
Are there specific screen densities that this application requires?
As you can see, the manifest is a busy place; there’s a lot of things to keep an eye on. But don’t worry too much, most of the entries here are automatically taken care of by the creation wizards of Android Studio. One of the few occasions you will interact with it is probably when you need to add permissions to your app.
The manifest is also important for Google Play when it displays your app on the store. Your app won’t appear to devices that do not meet the requirements stipulated in your manifest file.
Application Entry Point
- 1.
An Activity class that the user sees first as soon as the app launches
- 2.
A layout file for the Activity class which contains all the UI definitions like text views, buttons, and so on
- 3.
The AndroidManifest file, which ties all the project resources and components together
Excerpt from AndroidManifest.xml
If the application has more than one Activity, there will be several activity nodes in the manifest file, one node for each Activity. The first line of the definition has an attribute called android:name; this points to the class name of an Activity. In this example, the name of the class is “MainActivity.”
The second line declares the intent-filter, when you see something like android.intent.action.MAIN, on the intent-filter node, it means the Activity is the entry point for the application. When the app launches, this is the Activity that the user will see.
Activities
You can think of an Activity as a screen or a window. It’s something that a user can interact with. This is the UI of the app. An Activity is a class that inherits from the android.app.Activity class (one way or another), but we usually extend the AppCompatActivity class (instead of Activity) so we can use modern UI elements but still make the app run on older Android versions; hence, “Compat” in the name AppCompatActivity, which stands for “compatibility.”
An Activity component has two parts, a Java class (or Kotlin if that’s your language of choice) and a layout file in XML format. The layout file is where you put all the definitions of the UI, for example, the text box, button, labels, and so on. The Java class is where you code all the behavior parts of the UI, for example, what happens when the button is clicked, when text is entered into the field, when the user changes the orientation of the device, when another component sends a message to the Activity, and so on.
In Figure 5-2, the boxes show the state of an Activity on a particular stage of existence. The name of the method calls are embedded in the directional arrows which connect the stages.
When the Android Runtime launches the app, it calls the onCreate() method of the main Activity which brings the state of the Activity to “created.” You can use this method to perform initialization routines like preparing event handling codes and so on.
The Activity proceeds to the next state which is “started”; the Activity is visible to the user at this point, but it’s not yet ready for interaction. The next state is “resumed”; this is the state where the app is interacting with the user.
If the user clicks anything that takes the focus away from the Activity (answering a phone call or launching another app), the runtime pauses the current Activity and it enters the “paused” state. From there, if the user goes back to the Activity, the onResume() function is called, and the Activity runs again. On the other hand, if the user decides to open a different application, the Android Runtime may “stop” and eventually “destroy” the application.
Intents
Wrong way to activate another Activity
Android’s architecture is quite unique in the way it builds application. It has this notion of components instead of just plain objects. Android uses Intents as a way for its components to communicate; it also uses the same Intents to pass messages across components.
The reason Listing 5-2 won’t work is because an Android Activity isn’t a simple object, it’s a component. You cannot simply instantiate a component in order to activate it. Component activation is done by creating an Intent object and then passing it to the component you want to activate, which, in our case now, is another Activity.
How to activate another Activity
It may look like there’s a lot of things to unpack on our sample codes, but don’t worry, I’ll explain the codes with more context as we move further along in the coming chapters.
Summary
Android applications are made up of loosely coupled components. These components communicate via Intent objects.
An app’s entry point is usually a launcher Activity. This launcher Activity is designated in the app’s AndroidManifest file.
The manifest file is like a glue that holds together the components of the application; everything the application has, can do, or cannot do is reflected in the manifest.