In an ecosystem Android concept Activity is the fundamental building block of any application with which the user interacts. In simple terms, it is a single screen with an interface that displays buttons, text, images, and other controls. When you open the messenger, you see a list of chats - this is one activity, and when you go to a specific correspondence, another one starts. Understanding how this component works is critical not only for developers, but also for advanced users trying to understand the reasons for application crashes or strange system behavior.
However, Activity is not just a picture on the display. This is a complex software object managed by the operating system through a special manager. The system itself decides when to create an instance, when to pause it, and when to completely destroy it to free up memory. It is this automation that allows Android to work effectively on devices with different amounts of RAM, but it also often becomes a source of problems if the application is written in violation of life cycle rules. In this article we will analyze in detail the internal structure of the component, its state and how to avoid common mistakes when working with it.
Many beginners confuse activities with the application itself, considering them synonyms. This misconception can lead to a misunderstanding of architecture Android. One application can consist of dozens of different Activitys, each of which is responsible for its own unique use case. Moreover, different applications can use each other's activities if security settings allow this. For example, when you click the "Share" button in the browser and select a social network, you are actually launching Activity someone else's application within the context of your current activity.
Architectural role of Activity in the Android system
Component Activity acts as an entry point for user interaction with application. In the manifest file AndroidManifest.xml activities are declared as elements that can be launched by the system. Without at least one main activity, the application cannot be launched via the desktop icon. This is the central link that connects the user interface (UI) with the logic of the app. When you touch the screen, the system redirects this event to the currently active one. It is important to understand the difference between an activity and other components, such as Activity.
It is important to understand the difference between an activity and other components such as Service or BroadcastReceiver. Services operate in the background and have no visual representation, and receptors react to system events. Activity always focused on dialogue with a person. It loads the interface layout via method setContentView and handles button clicks, list scrolling, and text input. Moreover, it exists in its own window, which can occupy the entire screen or only part of it if multi-window mode is used.
The system manages the stack of activities, arranging them into a navigation history. When you move from screen A to screen B, the first activity is not destroyed immediately, but is placed on the stack. Pressing the Back button pops it from the stack and returns it to the active state. This mechanism provides the intuitive navigation that smartphone users are accustomed to. However, the developer must manually manage which data is saved when leaving the screen, and which can be lost.
⚠️ Warning: Never attempt to create instances Activity manually through the operator
new. This will crash the application because the object will not be initialized correctly by the system. The launch should always occur throughIntent.
The architecture Android assumes that activities can be destroyed by the system at any time when it needs memory. This means that the state of the interface is not guaranteed unless you save it explicitly. Activity is a temporary container for the UI, not a data store. Long-term storage of information should be carried out in databases, files or cloud services, which the Activity accesses as needed.
Activity life cycle: key states and methods
Life cycle Activity is a sequence of states through which a component passes from the moment of creation to completion destruction. Understanding this cycle is a must for writing stable code. The main stages are regulated by callback methods that the system calls at certain points in time. Ignoring these methods or performing heavy operations on them often results in the application being listed as not responding (ANR).
The method that is called first is onCreate(). This is the initialization point where the interface is loaded, variables are bound, and saved state is restored. This is where the code setContentView(R.layout.main)is executed that connects the Java or Kotlin code with the XML screen markup. After creation, the activity goes into the “Launched” state, but is not yet visible to the user. Next comes the onStart()method, which prepares the component for display.
The most important thing for the user is the onResume()method. When it is executed Activity becomes visible and receives input focus. The user can interact with the interface. If at this moment you launch another application or rotate the screen, the system will call onPause() and onStop(). In the method onPause() it is necessary to quickly save critical data, since after this the activity can be killed by the system without warning. Heavy calculations are prohibited here.
- 🔄 onCreate(): Creating an object, loading resources and interface.
- 👁️ onStart(): The activity becomes visible, but not yet interactive.
- ▶️ onResume(): Full activity, the user can press buttons.
- ⏸️ onPause(): Loss of focus, time for autosave drafts.
- 🛑 onStop(): The activity is completely hidden by other windows.
- 🗑️ onDestroy(): Permanently removing the object from memory.
Method onDestroy() is called either when the user closes the application or when the system decides to release resources. This method should unsubscribe from events, close database connections, and stop animations. If this is not done, a memory leak may occur, which will slow down the entire smartphone over time. The loop is closed, and the object becomes a candidate for garbage collection (Garbage Collection).
Use logging in each lifecycle method (for example, Log.d("Lifecycle", "onCreate")) to monitor in real time the behavior of the application in Logcat during debugging.
Configuration changes and screen rotation
One of the most common problems that developers and users encounter is the behavior of the application when the screen is rotated. When you rotate your smartphone from portrait mode to landscape mode, the configuration of the device changes. By default Android reacts to this event by completely destroying the current one Activity and creating a new one from scratch. This is done so that the system can redraw the interface to fit new screen sizes by loading an alternative layout from the folder layout-land.
For the user, this process often looks like a short flashing of the screen or a reset of progress if the data has not been saved. For example, if you were typing text into a form and turned your phone, the text might disappear. This happens because the old instance Activity was killed, and the new one was created clean. To avoid data loss, the system provides a mechanism onSaveInstanceState()that allows you to save primitive data types in a special Bundle before destruction.
It is also possible to prevent the re-creation of an activity when rotating by adding an attribute android:configChanges="orientation|screenSize" to the manifest. In this case, the system will not kill Activity, but will simply call the method onConfigurationChanged(). However, this approach is considered outdated for complex interfaces, since it shifts the responsibility for redrawing the layout onto the shoulders of the developer, which often leads to layout bugs on different devices.
⚠️ Attention: Handling screen rotation through
configChangesmay lead to the application being displayed incorrectly on tablets or devices with non-standard proportions screen. Use responsive layouts instead of locking rotation.
The modern approach involves using architectural components such as ViewModel. They allow you to store data separately from Activity. When an activity is destroyed by rotation, the ViewModel survives and is automatically bound to a new instance of the activity. This provides a seamless experience for the user: data remains in place, the interface is rebuilt, and the operating logic is not interrupted.
Launching an Activity and transferring data through Intent
Interaction between screens in Android is carried out using an object Intent. This is a kind of sending message that tells the system: “I want to open this screen” or “I want to perform this action.” Intent can be explicit when you specifically specify the target class Activity, or implicit, when you describe the action (for example, “open a link” or “take a photo”), and the system itself selects the appropriate application.
To transfer data from one screen to another, use the method putExtra() inside the Intent object. You can pass strings, numbers, lists, and even serializable objects. On the receiving side in the method onCreate() this data is retrieved through getIntent().getExtras(). This is a standard communication mechanism that allows applications to be modular. For example, the product details screen can be universal and accept product IDs from a list, from a search or from recommendations.
Intent intent = new Intent(this, DetailActivity.class);intent.putExtra("product_id", 12345);
intent.putExtra("is_favorite", true);
startActivity(intent);
In addition to transmitting data, Intent allows you to receive the result back. To do this, use the method startActivityForResult() (in older versions of the API) or the new API Activity Result Launcher. This is necessary when one activity must wait for an action from another. A classic example: you open a gallery to select a photo, make a selection, and the gallery returns control of your activity along with the path to the selected file.
☑️ Checking the correctness of the Intent
Task stack and Launch Modes
Behavior The activity stack can be flexibly configured using so-called launch modes (Launch Modes). The default mode is standard, in which each new request to open an activity creates a new instance of it on the stack. This is convenient for most scenarios, but sometimes leads to the accumulation of duplicate screens in the navigation history, which can confuse the user when pressing the Back button.
Mode singleTop prevents the creation of duplicates if instances of such an activity are already at the top of the stack. Instead of creating a new object, the system will redirect the new one Intent to an existing instance via the onNewIntent()method. This is often used for notification screens or chats where there is no need to open endless copies of the same conversation. The mode singleTask goes further: it clears the stack of all activities above the target, making it the only one in its task.
| Launch mode | Behavior on the stack | Typical use |
|---|---|---|
standard |
Always creates a new instance | Regular navigation screens |
singleTop |
Does not create if already at the top | Search screens, news feeds |
singleTask |
Clears the stack to this activity | Application main screen |
singleInstance |
Isolated stack, only one copy | Call screens, system dialogs |
Using the mode singleInstance creates a completely isolated task stack. It can only contain one such Activity. If you launch another activity from it, it will open in a separate, parent stack. This is a specific scenario, rarely used, for example, for incoming call screens, which must overlap everything else and be unique in the system.
What is Affinity (task affinity)?
Affinity is an attribute that determines which “task” (Task) an Activity belongs to. Tasks are grouped into recent application histories. By changing taskAffinity, you can place a specific screen in a separate card in the “Recents” menu, regardless of the main application.
Typical errors and memory leaks
Incorrect work with Activity is the main cause of memory leaks in applications on Android. The most common mistake is storing a reference to an activity in static variables or singletons with a long lifetime. Since the activity contains links to all Views (buttons, texts), and the Views contain the application context, such a link keeps the entire interface in memory even after the user has left the screen. The garbage collector cannot remove such an object.
Another problem is related to asynchronous tasks. If you started downloading data from the network in a separate thread inside an activity, and the user closed the screen before the download was completed, the completion callback will still try to update the interface of a non-existent activity. This will result in an exception IllegalStateException or an attempt to change the UI from a background thread, which is prohibited by the system. It is necessary to use WeakReference or architectural components for safe work with the life cycle.
It is also a common mistake to perform heavy operations in a method onCreate(). Reading large files, complex calculations, or synchronous database queries in this method will block the main thread. If the operation lasts more than 5 seconds, the system will show the user an “Application Not Responding” (ANR) dialog and prompt you to close it. All long-running operations must be moved to background threads or coroutines.
⚠️ Attention: The interfaces of libraries and Android versions may be updated. Always check the official developer documentation before implementing complex task stack management scenarios, as the behavior
launchModemay have nuances in different OS versions.
To diagnose memory and lifecycle problems, developers use the tool Android Profiler i LeakCanary. These utilities allow you to see the link graph and understand why Activity it is not removed from memory. Regular profiling helps to find hidden leaks that appear only after long-term use of the application.
The main rule of development: An Activity is a fragile UI controller, not a data store. All business logic and state should be placed in separate classes (ViewModel, Repository), independent of the screen life cycle.
Frequently asked questions (FAQ)
Is it possible to launch an Activity without an interface (without an XML layout)?
Technically, you can call a method startActivity() without installing content via setContentView(). In this case, a blank black screen will open. However, this defeats the purpose of the component. For background tasks without an interface, you should use Service. An empty activity will consume system resources in vain.
Why does the application restart when minimized on some smartphones?
This happens due to a lack of random access memory (RAM). When you minimize an application, it Activity goes to onStop()state. If the system urgently needs memory for another application, it can kill the process completely. When you return, the activity is created again. Proper state saving in onSaveInstanceState allows data to be restored without the user noticing the restart.
What is the difference between finish() and onDestroy()?
finish() is a method that you call programmatically to tell the system: “I'm done with this screen, close it.” After calling finish() the system automatically launches a chain of kill methods, including onDestroy(). onDestroy() zhe - this is the callback that the system calls at the last stage of the life cycle, regardless of whether you called finish() yourself or the system killed the process due to lack of memory.
How to pass a complex object between Activity?
To pass objects they must implement an interface Serializable or, which is preferable for performance, Parcelable. The object is packed in Intent via putExtra(). If the object is too large (for example, a Bitmap of an image), it is not recommended to pass it through Intent - it is better to save it to a temporary file or to a database and pass only a link or ID.
What is Task Affinity and why do you need it?
Task Affinity determines which task group (card in the recent applications menu) Activitybelongs to. By default, all screens of the same application have the same affinity. By changing this parameter in the manifest, you can force a specific screen to open in a separate history card, which is used in widgets or shortcuts for quick access to certain functions.