Managing App Configuration
1. Using BuildConfig
| Field | Type | Description |
|---|---|---|
| BuildConfig.DEBUG | Boolean |
Indicates if the app is built in debug mode. |
| BuildConfig.APPLICATION_ID | String |
Package name of the application. |
| BuildConfig.VERSION_CODE | Int |
Version code of the app as defined in build.gradle. |
| BuildConfig.VERSION_NAME | String |
Version name of the app as defined in build.gradle. |
Example: Accessing BuildConfig in Kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (BuildConfig.DEBUG) {
Log.d("MainActivity", "App is running in debug mode")
}
val versionName = BuildConfig.VERSION_NAME
Log.d("MainActivity", "App Version: $versionName")
}
}
Note:
BuildConfig fields are generated at compile time and are not modifiable at runtime.2. Creating Build Variants
| Variant Name | Description | Typical Use Case |
|---|---|---|
| debug | Build variant for development and testing with debugging enabled. | Local development, debugging, performance profiling |
| release | Build variant for production deployment with optimizations. | App store release, performance optimization |
Example: Build Variant Configuration in build.gradle.kts
android {
buildTypes {
getByName("debug") {
isDebuggable = true
applicationIdSuffix = ".debug"
}
getByName("release") {
isMinifyEnabled = true
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
}
}
flavorDimensions("version")
productFlavors {
create("free") {
dimension = "version"
applicationIdSuffix = ".free"
}
create("paid") {
dimension = "version"
applicationIdSuffix = ".paid"
}
}
}
Note: Build variants allow you to customize your app for different environments or user segments without maintaining separate codebases.
3. Setting Application Class
In Android, the Application class is a base class for maintaining global application state. You can customize this class to initialize global variables, set up logging, or perform other application-level operations.
| Property | Description | Example |
|---|---|---|
| android:name | Specifies the custom Application class to use in the manifest. | <application android:name=".MyApplication"> |
Example: Custom Application Class
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize global state here
Log.d("MyApp", "Application created")
}
}
Example: Registering Application Class in Manifest
<application
android:name=".MyApplication"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
</application>
4. Initializing in Application
Example: Application Class Initialization
import android.app.Application
import android.util.Log
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Log.d("MyApp", "Application initialized")
// Initialize third-party libraries here
// e.g., Firebase, Crashlytics, etc.
}
}
| Property | Description | Usage |
|---|---|---|
| onCreate() | Called when the application is starting, before any other components | Use for global initialization logic |
| context | Application context for accessing global resources | Access shared preferences, databases, etc. |
Note: The Application class is instantiated before any other component, making it ideal for initializing libraries that require global setup.
5. Using AndroidManifest.xml
| Element | Description | Usage |
|---|---|---|
| <manifest> | Root element of the AndroidManifest.xml | Must be present at the top level |
| <application> | Defines the application's metadata and components | Contains all app-level configurations |
| <activity> | Declares an Activity component | Used to define UI screens |
| <service> | Declares a Service component | Used for background tasks |
| <receiver> | Declares a BroadcastReceiver component | Used for handling broadcasts |
| <provider> | Declares a ContentProvider component | Used for sharing data between apps |
Example: Declaring an Activity
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<application>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Example: Declaring Permissions
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application>
...
</application>
</manifest>
Note: The
android:name attribute in components can be a full class name or a relative path from the package.
Warning: The
android:exported attribute must be set to true for activities that are launched by the system (e.g., launcher activities).
6. Setting Activity Attributes
| Attribute | Description | Values | Notes |
|---|---|---|---|
| android:name | Activity name | com.example.MainActivity |
Must be fully qualified class name |
| android:label | Activity label | @string/app_name |
Used in launcher and title bar |
| android:theme | Activity theme | @style/Theme.AppCompat.Light |
Applies to this activity only |
| android:exported | Can be launched by components outside app | true or false |
Required for launchable activities |
| android:launchMode | Activity launch behavior | standard, singleTop, singleTask, singleInstance |
Determines how new instances are created |
| android:screenOrientation | Screen orientation | portrait, landscape, sensor |
Controls device rotation behavior |
Example: Declaring Activity in Manifest
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="portrait">
</activity>
7. Configuring Application Theme
| Property | Value | Description |
|---|---|---|
| android:theme | @style/Theme.AppCompat.Light |
Applies a theme to the entire application |
| android:windowBackground | @drawable/background_drawable |
Sets the background for the window |
| colorPrimary | ?attr/colorPrimary |
Primary color for app elements like action bar |
| colorSecondary | ?attr/colorSecondary |
Secondary color for UI components |
Example: Define a Custom Theme
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimary">@color/primary_color</item>
<item name="colorPrimaryDark">@color/primary_dark</item>
<item name="colorAccent">@color/accent_color</item>
</style>
</resources>
Example: Apply Theme in Manifest
<application
android:theme="@style/AppTheme">
...
</application>
Note: Themes in Android are defined in
res/values/themes.xml or within styles.xml.
Warning: Avoid using
android:theme in individual activities unless you want to override the app-wide theme.
8. Using Metadata Tags
| Tag | Description | Usage |
|---|---|---|
| android:name | Unique identifier for the metadata tag | <meta-data android:name="com.example.api_key" android:value="secret123" /> |
| android:value | String value of the metadata | <meta-data android:name="version" android:value="1.0.0" /> |
| android:resource | Reference to a resource (e.g., string, integer) | <meta-data android:name="config_resource" android:resource="@string/config_value" /> |
Example: Reading Metadata in Kotlin
val metadata = packageManager.getApplicationInfo(
packageName,
PackageManager.GET_META_DATA
).metaData
val apiKey = metadata.getString("com.example.api_key")
val version = metadata.getString("version")
Note: Metadata tags are read-only and must be defined in the
AndroidManifest.xml.9. Setting Up Deep Link Handling
Deep links allow your Android app to handle URLs that open specific screens or perform actions within the app. This is particularly useful for integrating with web services, sharing content, or enabling external apps to launch your app.
| Component | Description | Notes |
|---|---|---|
| Intent Filter | Used in AndroidManifest.xml to declare which deep links your app can handle. |
Must include <intent-filter> with appropriate <action>, <category>, and <data> elements. |
| Data URI | Defines the scheme and host of the deep link (e.g., https://myapp.com). |
Can include path, port, and other components to match specific URLs. |
| Activity | The activity that will be launched when the deep link is triggered. | Must have android:name attribute set to the full class name. |
Example: Declaring Deep Link in Manifest
<activity
android:name=".DeepLinkActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="myapp.com"
android:pathPrefix="/deep" />
</intent-filter>
</activity>
Example: Handling Deep Link in Activity
class DeepLinkActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_deep_link)
val uri = intent.data
if (uri != null) {
// Handle the deep link data
val path = uri.path
val param = uri.getQueryParameter("param")
}
}
}
Note: Ensure that
android:exported="true" is set for the activity to allow external apps to launch it.
Warning: Make sure the
<data> element in the intent filter matches the URL structure exactly to avoid mismatches.
10. Managing Feature Flags
| Flag Name | Type | Default Value | Description |
|---|---|---|---|
| feature_new_ui | Boolean |
false |
Enables the new user interface for the app |
| feature_push_notifications | Boolean |
true |
Controls whether push notifications are enabled |
| feature_analytics | Boolean |
true |
Enables or disables analytics collection |
Example: Feature Flag Usage in Kotlin
class FeatureFlags {
companion object {
const val NEW_UI = "feature_new_ui"
const val PUSH_NOTIFICATIONS = "feature_push_notifications"
const val ANALYTICS = "feature_analytics"
}
}
fun isFeatureEnabled(flag: String): Boolean {
return when (flag) {
FeatureFlags.NEW_UI -> false
FeatureFlags.PUSH_NOTIFICATIONS -> true
FeatureFlags.ANALYTICS -> true
else -> false
}
}
Note: Feature flags can be managed via backend services or local configuration files.