Using the Android Context and Manifest to Unveil the Android System Mechanics (2025 Edition)

Introduction
All Android Developers come across the Android Context daily even for the most basic applications, but because the Context
can be used under various circumstances for different reasons, it can be hard to understand, resulting in several developers forming varying impressions around it.
Consequently, many developers will just “pass a context” when needed through the Application
or Activity
objects without further thinking since their code will build and run; a tactic that may lead to memory leaks and nasty app crashes due to poor usage of the Context in the application code.
This ambiguity about what the Context is—or why it is used—prevents developers from seeing the bigger picture of their code and the libraries they integrate.
But much of the confusion around the Context begins by not realizing how closely the Manifest is related to the Context and that by looking at both together, we can reveal much about how apps are coupled with the Android System.
This article will approach the Manifest and the Context in respect to the underlying Android architecture, for the reader to understand what they semantically represent from an application’s mechanics standpoint.
For that, this article will intentionally avoid code technicalities, and stick to what the Context
really represents, and the problems it is called to solve because understanding should precede learning and not the other way around.
The Application & the Android System
When you install an application, it is given its own unique Linux User ID and runs in its own instance of the Android Runtime (ART). Thus, each application is completely isolated with all its resources inaccessible to every other app.
When you run an application, it is also restricted from constructing or managing even its very own components (activities, services, etc.) by direct code. Instead, it requests the Android System to do that on its behalf.
Overall, this isolation approach assures a more secure, better structured, and less error-prone application due to leaving much of the responsibility to the Operating System, rather than to developer code.
But if Android is that restrictive to its apps, then two issues need to be addressed.
- Apps need a way to communicate with the Android System, so they can request it to construct or provide components and resources that are inaccessible by direct filesystem or code manipulations.
- The Android System should keep track of all installed applications and their components, to launch or provide them back to the caller if there’s a matching request.
To address the above problems the Context and the Manifest respectively come to the rescue, and as you can see there is an obvious correlation between them.
So how does it all fit?
- The Manifest is about how the app declares (to the OS) what components can be used
- The Context is how the app “talks” to the system when it wants something.
So, every time a Context does something important, it’s usually referencing some resource or component the OS learned about through the Manifest.
Application Manifest
When an application is first created, the Android System knows nothing about it unless that information is stated in the AndroidManifest.xml
file.
Even to have the app’s icon at the App Drawer, an activity needs to be declared as the launching activity via an implicit intent declaration (using an intent-filter
) in the manifest.
Within the <manifest>
tag of AndroidManifest.xml
, you define:
- Package Information of the application, for the OS to add the app to the Application Layer of the Android Software Stack and assign a unique user to run it, so the app can become reachable after installation
- Permissions using the
<permission>
tag for Android to know what restricted hardware and software resources should be enabled during app execution - and any custom subclass implementation of the Four Application Components for Android to be able to provide them upon request.
- These are
<activity>
for Activities,<service>
for Services,<provider>
for Content Providers, and<receiver>
for Broadcast Receivers.
All four component types declared in the manifest play a critical role in Android’s Inter-Process Communication (IPC) infrastructure.
Inter-Process Communication (IPC) and Manifest
At its core, Android uses a custom implementation of the Binder framework — a lightweight Remote Procedure Call (RPC) system optimized specifically for Android’s needs. When your app communicates with system services or other applications, it’s actually using Binder IPC under the hood.
As we will see Manifest’s main role will be to register the IPC components so the Android OS can lauch them as Contexts with some lifecycle or consume them from a given context’s lifecycle.
So, when you declare a component in your manifest, you’re essentially registering it with the system for potential cross-process communication.
The android:exported
attribute (required since Android 12 for components with intent filters) explicitly controls whether a component can be accessed from other applications, or stays encapsulated in your app.
For example:
- An exported Activity can be launched by other apps through an Intent
- An exported Service can be bound to or started by other apps
- An exported ContentProvider makes its data accessible to authorized apps
- An exported BroadcastReceiver can receive broadcasts from the system or other apps
Intents and the Role of the Manifest
But why does Android need subclasses of these four types to be declared at the manifest?
Let’s start with intents…
Explicit Intents
When you make an explicit intent from some activity to open another activity, you never directly create the new activity object and pass variables to its constructor.
Instead, you use an explicit intent to ask Android to create and launch the target activity (specified by its class name) thanks to the associated manifest declaration on your behalf and pass a bundle with data (rather than passing constructor parameters).
val intent = Intent(this, NextActivity::class.java)
startActivity(intent)
Here, the system sees “you want NextActivity
” and, because NextActivity
is indexed in the manifest, knows how to create and run it. If NextActivity
was not declared in the manifest, the system wouldn’t be able to launch it.
Because the Android Operating System has already indexed all the components by package AND class name during app installation — thanks to the associated manifest declarations — , it knows where to find the component you requested by class name, in order to construct and launch it on behalf of the caller.
Implicit Intents
On the other hand, when you make an implicit intent, you don’t really know what activity will handle your request.
The Android System will check all the Manifest declarations that fit the request’s intent-filter
of every installed app, to figure what set of activities (or other component types) can handle your “intention”.
This is how features like “share” or “open with” can trigger other apps. Again, the system references each app’s manifest to figure out which component can handle the request.
Bundles in Intents
Passing data in a Bundle
with an Intent is a necessity because the OS stands in the middle —it constructs the target component and needs a standard way to serialize and deserialize data.
This is why only certain data types are allowed. Android must ensure it can handle them consistently.
Bundles pose yet another Inter-Process Communication tool, as they are meant to pass data via the Android OS between different apps as well.
Pending Intents
PendingIntents are vital for features like notifications, widgets, Alarms, or scheduling future tasks via WorkManager. You create a PendingIntent
using your app’s context:
val intent = Intent(context, TargetActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE // or FLAG_UPDATE_CURRENT, etc.
)
The OS can later “fire” this Intent as though your app did it, including using your app’s identity and permissions. If TargetActivity
is not declared in the manifest, the system can’t launch it, even from a pending intent. In Android 12+, you must declare FLAG_IMMUTABLE
or FLAG_MUTABLE
to indicate how the PendingIntent can be modified for security reasons.
Intents TL;DR
Intents is Android’s way to have a Context (which is discussed later) ask the OS to to construct and deliver application components on behalf of the caller app (like starting other activities, services, or delivering a broadcast).
Application Components in the Manifest
- Activities & Manifest: Android OS gets aware of all the activities so it can create and launch them explicitly or implicitly upon intent requests.
- Services & Manifest: Android gets aware of all the available services so it knows what background operations it can run.
- Content Providers & Manifest: Android is aware of all the content providers, so it can provide content to your app or other apps when needed.
- Broadcast Receivers & Manifest: Android is aware of all receivers registered to listen to a broadcast (via manifest declaration), so even when the app is not running, the receivers that are registered to a specific broadcast will be notified.
Side Note on Receivers:
It is not obligatory to define Receivers in the manifest. Apps can receive broadcasts either by “manifest-declared receivers” (using the <receiver>
tag at manifest) where the registered receiver will listen to broadcasts permanently, or by “dynamically-declared receivers” at the runtime (using the Context.registerReceiver()
method) where the receiver “listen” to broadcasts during the time you asked it to “listen”.
So, these four application components when declared at the manifest, let the Android OS know they are there, so it can take action when some request by your app (or some other app) fits their existence, explicitly or implicitly.
What is Android Manifest — TL;DR
The Manifest is the app’s “declaration” to the system:
- It makes the OS aware of what your app can do, which components it has, and what permissions it needs.
- It provides the foundation for cross-app interaction via intents’
intent-filter
s or content providers so your app can also access other apps’ components and vice versa! - Modern Android versions require extra clarity on whether components can be accessed externally. If you omit details like
android:exported
on Android 12 or higher, your app might fail to install or behave unexpectedly.
Context & Non-Context Manifest Components
Before talking about the Context (which follows next), we should make clear that not all manifest entries refer to Context
subclasses.

Context Manifest Components
These manifest components descend from the Context
class and perform UI or background operations. They are directly constructed and launched by the OS and because of that, they have a Lifecycle whose state is administered by the OS.
These manifest components are:
- Application
- Activity
- Service
Non-Context manifest components
Content Providers
and Broadcast Receivers
are non Context
class descendant objects, however, they consume acontext
as their role is heavily dependent on the Android Operating System.
- Content Providers
Source: developer.android.com
When you want to access data in a content provider, you use the
ContentResolver
object obtained from your application'sContext
to communicate with the provider as a client.
val cursor = context.contentResolver.query(
MY_CONTENT_URI,
null, null, null, null
)
The ContentResolver
belongs to your app’s context. The provider itself is recognized from the manifest, but the actual queries always use a Context
as a communication vehicle to be provided with the desired content.
- Broadcast Receivers
Source: developer.android.com
Base class for code that receives and handles broadcast intents sent byContext.sendBroadcast(Intent)
.
That is, when a broadcast occurs (e.g., from the system or another app calling sendBroadcast(intent)
), the OS uses the manifest or runtime registration to determine which receivers should handle it. The actual method signature is onReceive(Context context, Intent intent)
, indicating how the broadcast arrives with a context reference. If your app is in the background, the system might spin up a process, attach a context, and deliver the broadcast.
Android Context
Let’s start with the official Context definition that even if it might appear odd initially, it should make perfect sense by the end of the article…
Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.
Having a better grasp of the manifest, you apprehend that with so much burden falling to the Android System, your app needs a handle to the Android OS to pass its requests. That handle comes in the form of an Android Context.
Abstract Class: Subclasses
This is an abstract class whose implementation is provided by the Android system.
As seen from the Google definition, context is an abstract class, which means you cannot find any direct Context objects, but you can find Context subclasses, such as Application
, Activities
, Services
, etc. So when dealing with these classes, you are dealing with a Context.
And since the Context implementation is provided by Android, to create and launch Context objects, the construction needs to be conducted by OS managed construction mechanisms, such as intents, rather than by direct code with classic constructors.
Activity
is a specializedContext
for UI tasks.Service
is a specializedContext
for background tasks.Application
is a global, singleton-like context for the entire app, useful for things that must persist across activities (like a database manager).
But if the Context implementation is provided by Android, that means the Context can act as the intermediary between your App and Android, and thus as a window to Global Device Information.
Interface to global information about an application environment.
Like if your phone is using a light or dark theme, if it is in portrait or landscape mode, but also allow for seamless integrations to global settings, like allowing Android to automatically apply the correct font size to a custom TextView
by joining the device’s global font-size setting with your custom SP value during layout inflation, or by returning the correct variation of a resource’s value.
Resources and Resource Variations
It allows access to application-specific resources and classes,
Yes, Resources too are provided by the Android System through the Context, and not by direct application code. Android provides resources by a [key/value] based mechanism that uses a context to request a resource’s value.
Resources — like strings, dimensions, layouts — come from res/
folders in your project, but you never do direct file access. Instead, you use context.getResources()
or context.getString()
. Android can automatically return the appropriate language/density variant. This approach is consistent from early Android, and though new resource qualifiers are introduced in new versions (for instance, new screen sizes or foldable categories).
This is not only secure as you don’t get filesystem access to the “res” folder, but it is also smart, as the Android System can even decide between returning different variations of a resource’s values based on Global Settings, like the device language preference to return the appropriate value of string resource kept in multiple language versions, or returning appropriate variation of an image, based on the pixel density and size of your device’s screen.
So, the Android Context binds your app with the Android System, for anything that cannot be done or retrieved without going through the Android System
Where Can I Find a Context?
Since the Activity
, Service
, and Application
classes are all Context
class descendants, if you are inside an Activity
method, this
is your Activity
context. In a Service
, this
is the service context. For a global reference, you might call getApplicationContext()
to retrieve the Application
context.
However, these contexts have different lifecycles:
- An Activity context exists only between
onCreate()
andonDestroy()
. - The Application context exists as long as the app process is alive.
Memory Leak alert!
But since the above classes have different lifecycles, passing for example an activity’s context as the android handle to something related to the entire app, you can cause a memory leak, preventing the Activity (and all its views and resources) from being garbage-collected.
Android Contexts: Choosing the Right Type for the Right Job
The BIG Question:
Why not just always use the ApplicationContext since all we need is a handle to Android and forget about memory leaks? Why use different life-cycled contexts?
Understanding context types comes down to three key factors: inheritance structure, capabilities, and lifecycle implications.
Context Inheritance and Capabilities:
Activity inherits from ContextThemeWrapper
, while Service and Application do not. This inheritance distinction is critical - the "Theme" in the name reveals its purpose. ApplicationContext
lacks UI capabilities and cannot inflate layouts, start activities, or display dialogs with proper theming.
Attempting UI operations with ApplicationContext
typically results in crashes like "Unable to add window -- token null is not valid" when showing dialogs.
Environmental Access:
Different contexts provide access to different parts of your application environment. Activity
contexts include theme information, window features, and UI thread access. When two activities use different themes (light/dark), they interpret theme attributes differently despite accessing the same resources.
ApplicationContext
provides application-wide access but lacks awareness of UI state or current theme attributes, making it unsuitable for UI operations that require theme-specific resource resolution.
Lifecycle and Memory Considerations
For non-UI components that outlive individual screens (like database access, network clients, or other singletons), ApplicationContext
prevents memory leaks. When a long-lived object holds an Activity
context reference, it prevents that Activity
from being garbage collected after destruction (like during configuration changes).
Using ApplicationContext
in these scenarios ensures the reference points to the application-wide context that exists throughout your app’s entire lifecycle.
Outro: Always select your context based on purpose.
Activity
context for UI operations,ApplicationContext
for long-lived components. This approach ensures proper functionality while preventing memory leaks — a fundamental principle in sound Android architecture.
The roles of Context as a parameter in method calls
Passing a context in method calls in Android is very frequent. However, the fact that you may pass a context for completely different reasons, is a major source of confusion for developers, as the context’s role is not clear.
So, when you include a context in a method call, the context might play one of the following three roles:
- Passive role: To ask the OS for some value (eg: what is the value of a resource).
- Active role: To ask the OS to perform some action on your behalf (eg: launching a component through an Intent, inflate some layout, display a message, etc).
- Binding role: To connect your app to a distant entity or mechanism managed by the OS (eg: connecting to an SQLite database, where that binding will be used in both “active” and “passive” roles to read or update data in the database — in such cases, you almost always use an Application Context, as the binding should exist throughout the lifetime of the entire app).
In any case, a context is always the OS intermediary that stands between your code and the Android System, delivering requests in order for some information to be retrieved or for some action to take place.
So the next time you use a “context” in a method call, you will know it is the vehicle that will reach the OS and ask it to execute or retrieve your method’s request.
The role of Context as a generated component?
Besides passing a context around in method calls, Activity
and Service
themselves are Context
generated objects (or components).
They don’t get instantiated by normal constructors; the Android system instantiates them via intents
. That’s why calling new MainActivity()
never triggers onCreate()
.
The OS must launch activities so it can manage their lifecycle states (onCreate
, onStart
, onResume
, etc.).

Component role: the role that represents a custom launchable component. These custom launchable components belong to the Application Layer of the Software Stack but extend or use classes defined in the Application Framework, and as such serve as a bridge between the application and the operating system.
When these Context descendant components are created and launched by the Android OS with mechanisms like “intents” (rather than directly through constructors), they obtain Lifecycle managed by the OS.
For example, for a class that extends the Activity class, if you try to instantiate it by normal means (MyActivity ma = new MyActivity();
) the onCreate()
method WILL NOT be called. Only if you start the Activity with an Intent, will the method be called (source).
So the role of Context as object, is to bridge its newly constructed subclass component (eg. Activity) with the Android System, so the latter can provide and update the Lifecycle of that component.
What Is Android Context — TL;DR
The Context is a class provided by Android, and as such, its job is to bridge your application code with the Android System. Through your Application class and other custom components that inherit from Context, your application gains the ability to access resources and functionalities reachable only by the Operating System.
When objects of such classes get instantiated by the Operating System (through an OS controlled instantiation mechanism, like “intents”), they become administered by the Operating System, and as such, they obtain lifecycle.
For anything else, passing a context as a parameter in method calls, allows this method to use the context as a channel of communication with the OS, in order to reach the OS and ask it to perform some action or return some resource.
Single-Activity Architecture: Context and Lifecycle in Modern Android
The Rise of Single-Activity Applications
The evolution of Android development has seen a significant shift from multi-activity applications toward single-activity architectures. In this approach, instead of creating a new Activity for each screen, developers build the entire application UI within a single Activity.
This fundamental change raises important questions about how Context and lifecycle management work when there’s only one Activity serving as the foundation for the entire application.
Single-Activity Apps with Fragments: The First Step
Before Jetpack Compose entered the scene, developers created single-activity applications using Fragments and XML layouts. In this model, the application would have just one Activity declared in the manifest, and this Activity
would serve as a container for various Fragments representing different screens:
// The one Activity declared in the manifest
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// The container where Fragments will be shown
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, HomeFragment())
.commit()
}
}
}
Despite having only one Activity
, the Context system remains essential. The single Activity
, created by the Android System, still provides the Context
bridge to the operating system. All Fragments share this Activity’s Context
for their UI operations, including inflating layouts and accessing resources. Fragments have their own lifecycle methods, but these are closely tied to and coordinated by the parent Activity’s lifecycle.
Jetpack Compose: The Next Evolution
Jetpack Compose takes the single-activity architecture further by eliminating the need for Fragments and XML layouts altogether. With Compose, developers define UI through composable functions rather than XML files:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
// Navigation happens inside Compose
MainNavHost() // This replaces Fragment transactions
}
}
}
}
However, the underlying Context system doesn’t disappear — it just changes how it’s accessed and used. In a Compose application, there’s still at least one Activity
declared in the manifest. This Activity
calls setContent()
instead of setContentView()
, establishing Compose as the UI framework. The Activity
continues to serve as the bridge between the application and the Android System, providing the Context
necessary for many operations.
Context Flow in Compose Applications
When using Compose in a single-activity architecture, the Context flow remains important but becomes less visible. The Activity’s Context is passed down through the composition system and made available through the LocalContext
composable:
@Composable
fun ScreenWithSystemAccess() {
// Getting the Activity's Context in Compose
val context = LocalContext.current
Column {
Button(onClick = {
// Using Context to show a toast
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show()
}) {
Text("Show Toast")
}
// Using Context to access resources
Text(text = context.getString(R.string.welcome_message))
}
}
Many Compose functions don’t directly require Context to build basic UI elements, making the Context dependency less obvious. However, operations like showing toasts, accessing resources, or using system services still need a Context.
This Context comes from the Activity, maintaining the fundamental Android model where the Context serves as the communication channel with the Android System.
Lifecycle Management in Compose
Understanding lifecycle in Compose applications requires seeing how Compose’s own lifecycle concepts interact with the Activity
lifecycle.
Compose introduces the concept of composition lifecycle — UI elements enter composition when they appear and leave composition when they disappear. This is handled through the Compose runtime and differs from the Activity lifecycle.
However, the Activity lifecycle still matters significantly. The Activity created by the OS still receives lifecycle events like onCreate
, onResume
, onPause
, and onDestroy
. These events can be observed within Compose through the LocalLifecycleOwner
:
@Composable
fun ScreenWithLifecycleAwareness() {
// This gives us access to the Lifecycle from the Activity
val lifecycleOwner = LocalLifecycleOwner.current
// We can observe lifecycle events from the Activity
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> { /* ... */ }
Lifecycle.Event.ON_PAUSE -> { /* ... */ }
Lifecycle.Event.ON_CREATE -> { /* ... */ }
Lifecycle.Event.ON_START -> { /* ... */ }
Lifecycle.Event.ON_STOP -> { /* ... */ }
Lifecycle.Event.ON_DESTROY -> { /* ... */ }
Lifecycle.Event.ON_ANY -> { /* ... */ }
}
}
// Register our observer to the lifecycle
lifecycleOwner.lifecycle.addObserver(observer)
// Clean up when this composable leaves composition
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
This means that while Compose has its own composition lifecycle, it doesn’t replace the Activity lifecycle — instead, the two work together. The Activity receives lifecycle events from the system and can forward these events to interested composables through the LocalLifecycleOwner.
State Collection and Lifecycle Awareness
The connection between Context, lifecycle, and state becomes particularly clear when we look at how Compose handles state collection. Compose offers two main approaches to collecting state from Flows: collectAsState
and collectAsStateWithLifecycle
:
@Composable
fun UserProfileScreen(viewModel: ProfileViewModel) {
// Basic collection - continues in background
val basicState = viewModel.basicStateFlow.collectAsState().value
// Lifecycle-aware collection - pauses in background
val lifecycleAwareState = viewModel.importantStateFlow
.collectAsStateWithLifecycle().value
// Use the states in UI...
}
The difference between these two functions hinges on lifecycle awareness. The basic collectAsState
function collects from a Flow whenever the composable is in composition, regardless of whether the application is in the foreground or background. In contrast, collectAsStateWithLifecycle
respects the Activity's lifecycle – it pauses collection when the Activity is in the background and resumes when the Activity returns to the foreground.
This lifecycle-aware collection is possible because Compose has access to the Activity’s lifecycle through the LocalLifecycleOwner. The function uses the Activity’s lifecycle events to manage the Flow collection efficiently, demonstrating how the Activity’s Context continues to influence application behavior even in a Compose-based UI.
The Continued Importance of Context
Even as Android development evolves toward more modern approaches like single-activity architectures and declarative UI with Compose, the fundamental Context system remains crucial. The Context still serves as the essential bridge between your application and the Android System, providing access to resources, system services, and lifecycle events.
What has changed is how we interact with this system. In multi-activity applications, each Activity provided its own Context. In single-activity applications with Fragments, one Activity Context is shared across multiple Fragments. In Compose applications, the Activity Context is made available through composable environment objects like LocalContext and LocalLifecycleOwner.
This evolution shows how Android’s fundamental architecture continues to adapt while maintaining its core principles. Understanding the role of Context and lifecycle in these modern approaches helps developers create applications that work efficiently with the Android System, regardless of which UI framework or architecture they choose.
Visualizing the Manifest & the Context

A good analogy to visualize the concept of the Manifest and the Context could be an old fashioned calling centre switchboard:
- The base is the Application Framework where all wires that connect every application component with the Android System emerge from.
- Each application through its manifest declarations exposes plug-holes for every declared component to the Android System, so it can construct them and put a context wire in order to manage them.
- And finally, each wire is the Android Context part of the constructed launchable component which binds that application component with the Android System.
So the manifest adds Applications to the Application Layer of the Software Stack and creates plugholes for each application and its components. When the Android System constructs a component that inherits from Context, a Context wire is automatically plugged into the newly constructed component’s plughole so the OS can link to it and manage it.
You can assume that during component destruction, its wire gets unplugged. While when another component gets constructed, a new wire emerges and connects to the corresponding manifest-declared plughole.
Testing & Design Patterns
Now you know why the context exists, you will appreciate the difference between unit and instrumented tests.
In a nutshell, unit tests do not require any interaction with the Android OS, and run your test code directly at the JVM, while the integration tests assume the involvement of the Android OS with your code at some point and thus they need to run on an emulator or real device, making them significantly slower and cumbersome than local unit tests.
So, instrumented tests are usually required when you need to perform something that involves heavily the OS and obviously involves a Context, or if you are testing custom components directly (like an Activity which is Context subclass).
(As a side-note, for simple cases where you just use a context that doesn’t require deep involvement of the OS, there are ways to mock a context and avoid running instrumented tests — but this is out of this article’s scope).
With all that in mind, if with design patterns like the MVVM (Model-View-ViewModel), which is endorsed by Google, you can keep all the Business Logic in the ViewModel, and keep that logic away from UI related code and from Data Layers (by providing mock data repositories with sample data), then your Business Logic should be clear of Context items, so you can test your ViewModels with local rather than instrumented tests, leading to faster testing, and a much clearer, and easier to debug code.
But to isolate the business logic it is necessary to understand when your code involves the Android OS, and when it doesn’t.
So, understanding how your apps are coupled with the Android System can help you to acknowledge even further the reasons behind choosing Design Patterns (such as MVC or MVVM) that promote the Separation of Concerns, and maybe even adjust the way you approach and write code!
Find more about testing here: https://developer.android.com/training/testing/fundamentals
Understanding Context’s Deeper Significance
As we’ve explored throughout this article, Context represents much more than just another API or parameter in Android development. It embodies the fundamental relationship between your application and the Android operating system itself. This relationship defines what makes Android development unique and distinct from general-purpose programming.
Consider what Android development would be without Context: if the Context system didn’t exist, every test could be run as a simple unit test, and Android would essentially become just a collection of libraries built on top of the Java Virtual Machine. Your application wouldn’t be an “Android app” in any meaningful sense — it would merely be a Java or Kotlin application that happens to use some additional libraries, capable of running on any operating system with a JRE installed.
Thus it is due to the Context that your app is truly an “Android app.” Context represents the essential bridge that connects your code to the Android platform, providing the communication channel through which all system interactions flow. Without this connection, the distinctive character of Android development would vanish.
Enjoyed the article?
SUBSCRIBE and CLAP on Medium
Ioannis Anifantakis
anifantakis.eu | LinkedIn | YouTube | X.com | Medium