Today we’re going to take a look at Android’s most basic and in the same time most important concept, which is an Activity. To create even the simplest “HelloWorld” app one should know what are the Activities and how to work with them.
What is an Activity ?
The simplest, an Activity is a single screen in Android application. The concept of Activities is unusual in programming and it’s specific to Android platform.
Every Activity in Xamarin consists of two components:
- UI (XML) – layout with user controls defined
- Code (C#) – implementing the behavior
Activities Back StackAndroid app starts its own Activities from other Activities. It may also start Activities that are defined by different apps, e.g. your Android app can offer a possibility to send an email. You don’t have to implement your own email sending client for that – it’s possible to use already existing email sending Activities (using Android Intents, which we’ll also cover one day) registered within another apps installed in the system which expose such “external calling” possibility. Then, this external app launches looking as if it was the part of your application. This is very powerful! When your email is finally sent, you are redirected back to your app from which you triggered email’s sending. How is that possible? In order to ensure such way of functioning, Android keeps all the Activities needed to perform a certain job (even if they come from different apps) in the same task. The “scope” of a task (when new task is created, what Activities it contains etc.) depends, among others, on Android version (e.g. starting from Android 7.0 many apps can be started in multiple windows in the same time on a single screen – in that case, the system keeps a separate task for each window). Within a particular task, several Activities are started. Each started Activity is pushed to the Activities Back Stack. The Activity being on the top of the stack has focus (is visible to the user). The previous Activities remain on the stack, but are stopped or even destroyed by Android system in certain cases (few more words about it in the next chapter). Activities Back Stack is a LIFO objects structure: when user presses Back button the current Activity is popped from the top of the stack and the state of the previous Activity is restored. The following figure visualizes this behavior:
Android Activities LifecycleWe already know the Activities are kept on Back Stack. We also need to know that Android OS may try to restart the application (after it crashed, for instance) at the last opened Activity. The OS may also pause the Activities when they’re not active or kill them when the device is low on memory. All those possible operations and states’ changes form Android Activities Lifecycle, which is a set of defined states in which every Activity may be: Let’s see what those states mean:
- Running – Activity is in the foreground (top of the activities stack); highest-priority Activity for OS
- Paused – Activity is in this state when still visible, but covered by another non-full sized Activity or when the device enters sleep mode; second-highest-priority Activity for OS
- Backgrounded/Stopped– Activity enters Backgrounded state when it’s overtaken by another, completely new Activity which is pushed on the top of the back stack; lowest-priority Activity for OS, which will be killed firstly in order to free resources
- Restarted – this state is not visible on the diagram, however it’s possible that Android (e.g. user using task manager or similar app) kills the app being in any of above-mentioned states; if the user wants to go back to this Activity later, it must be restarted (previous state must be retrieved).
Handling states changes – lifecycle methodsAndroid (and Xamarin) provides SDK methods that are called by the OS each time an Activity’s state changes. Those methods may be overridden and implemented for each Activity in order to react on states changes and ensure application’s stability. The following diagram visualizes the dependencies and flow of methods being called: Let’s see in what cases the particular methods should be implemented:
- OnCreate() – called when an Activity is created; used for initializing views and variables
- OnStart() – called immediately after OnCreate() finishes; UI refreshing can be handled here
- OnResume() – called after OnStart() finishes and also when Activity is restarted after being paused
- OnPause() – called when OS is about to pause or move the Activity to the background; here all resources-consuming objects should be cleaned-up, unsaved changes should be stored in some kind of persistent storage to be able to restore it when the Activity is revealed
- OnStop() – called when the Activity stops being visible to the user or is destroyed (e.g. when OS needs to release some resources)
- OnDestroy() – final method called on Activity just before it’s destroyed; it may not be called in some cases, so it’s better to clean-up resources in OnPause() and OnStop() methods.