Written by Abderraouf GATTAL. You should follow him on Twitter.
Android, an operating system that invaded more than 60% of the smartphones market which pushed developers like you to invest their efforts in building fabulous apps and to do so you should know some basics which we’ll cover in this part of the article and the other coming parts if Allah wills so.
First we’ll cover the main terms of the field, starting with Application, Activity and then we’ll explain the most important thing that every Android developer should understand which is the Lifecycle.
What do we mean by an App?
The word “App” is the abbreviation for “Application” which is a modern term for software application, and it is most often used in reference to a mobile app or a small piece of software that runs on a website, smartphone, tablet or other electronic devices, including smart TVs and smartwatches. Apps may or may not have a connection to the internet. It’s typically used to describe anything that isn’t a full-fledged software program, but even that line has become blurred.
Cool, now that’s what we meant by an App but what do we mean by Android App? you may say “ It’s a small piece of software that runs on Smartphone’s OS Android.”, well that’s true but as a developer you should know more about the technical aspect like it can be written using Kotlin, Java, and C++ programming languages. Android SDK (Software Development Kit) tools compile your code along with any data and resource files into an APK (Android Package), which is an archive file with an
.apk suffix. One APK file contains all the contents of an Android app and is the file that Android-powered devices use to install the app and Android Application are built using App components.
App components, what are they ?
App components according to the official Android Documentation are the essential building blocks of an Android app. Each component is an entry point through which the system or a user can enter your app. Some components depend on others.
There are four different types of app components:
- Broadcast receivers
- Content providers
Each type serves a distinct purpose and has a distinct lifecycle that defines how the component is created and destroyed. We will stick to Activities only in that part hoping that we will cover the others soon Inchaa Allah (with Allah’s willing).
The secrets of Activities
An activity is the entry point for interacting with the user. It represents a single screen with a user interface. For example, an email app might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email app, each one is independent of the others. As such, a different app can start any one of these activities if the email app allows it. For example, a camera app can start the activity in the email app that composes new mail to allow the user to share a picture. An activity facilitates the following key interactions between system and app:
- Keeping track of what the user currently cares about (what is on screen) to ensure that the system keeps running the process that is hosting the activity.
- Knowing that previously used processes contain things the user may return to (stopped activities), and thus more highly prioritize keeping those processes around.
- Helping the app handle having its process killed so the user can return to activities with their previous state restored.
- Providing a way for apps to implement user flows between each other, and for the system to coordinate these flows. (The most classic example here being share.)
Since we mentioned interaction between activities we should explain something very important to understand how it happens which is the Lifecycle.
Why all that buzz about Lifecycles ?
As a user navigates through, out of, and back to your app, the Activity instances in your app transition through different states in their lifecycle. The Activity class provides a number of callbacks that allow the activity to know that a state has changed: that the system is creating, stopping, or resuming an activity, or destroying the process in which the activity resides.
Within the lifecycle callback methods, you can declare how your activity behaves when the user leaves and re-enters the activity. For example, if you’re building a streaming video player, you might pause the video and terminate the network connection when the user switches to another app. When the user returns, you can reconnect to the network and allow the user to resume the video from the same spot. In other words, each callback allows you to perform specific work that’s appropriate to a given change of state. Doing the right work at the right time and handling transitions properly make your app more robust and performant. For example, good implementation of the lifecycle callbacks can help ensure that your app avoids:
- Crashing if the user receives a phone call or switches to another app while using your app.
- Consuming valuable system resources when the user is not actively using it.
- Losing the user’s progress if they leave your app and return to it at a later time.
- Crashing or losing the user’s progress when the screen rotates between landscape and portrait orientation.
But not caring about the lifecycle of each activity could cause you lots of problems you’ll lose days trying to resolve and may even fails.
And now since we understood the high importance of understanding lifecycles let’s get to the main concepts we should know.
To navigate transitions between stages of the activity lifecycle, the Activity class provides a core set of six callbacks: onCreate(), onStart(), onResume(), onPause(), onStop(), ** and **onDestroy(). The system invokes each of these callbacks as an activity enters a new state.
As the user begins to leave the activity, the system calls methods to dismantle the activity. In some cases, this dismantlement is only partial; the activity still resides in memory (such as when the user switches to another app), and can still come back to the foreground. If the user returns to that activity, the activity resumes from where the user left off. The system’s likelihood of killing a given process -along with the activities in it- depends on the state of the activity at the time. Activity state and ejection from memory provides more information on the relationship between state and vulnerability to ejection.
Depending on the complexity of your activity, you probably don’t need to implement all the lifecycle methods. However, it’s important that you understand each one and implement those that ensure your app behaves the way users expect.
You must implement this callback, which fires when the system first creates the activity. On activity creation, the activity enters the Created state. In the onCreate() method, you perform basic application startup logic that should happen only once for the entire life of the activity. For example, your implementation of onCreate() might bind data to lists, and instantiate some class-scope variables.
When the activity enters the Started state, the system invokes this callback. The onStart() call makes the activity visible to the user, as the app prepares for the activity to enter the foreground and become interactive. For example, 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.
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. When the interruptive event occurs, the activity enters the Paused state, and the system invokes the onPause() callback. If the activity returns to the Resumed state from the Paused state, the system once again calls onResume() method. For this reason, you should implement onResume() to initialize components that you release during onPause(), and perform any other initializations that must occur each time the activity enters the Resumed state.
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 the Activity is in the Paused state, and that you expect to resume shortly. There are several reasons why an activity may enter this state. For example:
- Some event interrupts app execution, as described in the onResume() section. This is the most common case.
- In Android 7.0 (API level 24) or higher, multiple apps run in multi-window mode. Because only one of the apps (windows) has focus at any time, the system pauses all of the other apps.
- A new, semi-transparent activity (such as a dialog) opens. As long as the activity is still partially visible but not in focus, it remains paused.
However, as mentioned above in the onResume() section, a Paused activity may still be fully visible if in multi-window mode. As such, you should consider using onStop() instead of onPause() to fully release or adjust UI-related resources and operations to better support multi-window mode.
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. In the onStop() method, the app should release or adjust resources that are not needed while the app is not visible to the user. For example, your app might pause animations or switch from fine-grained to coarse-grained location updates. Using onStop() instead of onPause() ensures that UI-related work continues, even when the user is viewing your activity in multi-window mode. You should also use onStop() to perform relatively CPU-intensive shutdown operations. For example, if you can’t find a more opportune time to save information to a database, you might do so during onStop().
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)
- the system is temporarily destroying the activity due to a configuration change (such as device rotation or multi-window mode)