Popular Searches
Popular Course Categories
Popular Courses

Managing Development, Testing, and Production Configurations

Managing Development, Testing, and Production Configurations

App Architecture, Libraries, and Build Management

Managing Development, Testing, and Production Configurations

Course: Android App Development

Topic: Managing Development, Testing, and Production Configurations

Course Link: Android App Development Course

Demo Registration: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction

Android applications usually pass through multiple environments before reaching end users. Developers create and debug features in a development environment, verify functionality in a testing environment, and prepare a stable release for production. Each environment may require different API endpoints, application identifiers, logging behavior, feature flags, credentials, and build settings.

Managing these configurations correctly helps prevent test data from entering production systems, reduces the risk of exposing sensitive information, and makes releases more reliable. Android Studio and Gradle support this process through build types, product flavors, build variants, source sets, manifest placeholders, resource overrides, and variant-specific dependencies.

A well-designed configuration strategy allows developers to build different versions of an application from the same codebase while keeping environment-specific behavior controlled and predictable.

2. Learning Objectives

  • Understand development, testing, staging, and production environments.
  • Learn the role of Android Gradle build types and product flavors.
  • Configure debug and release builds.
  • Understand build variants and source sets.
  • Use environment-specific API endpoints and application identifiers.
  • Manage configuration values through Gradle and Android resources.
  • Understand variant-specific dependencies and manifest configuration.
  • Protect secrets and sensitive configuration data.
  • Configure logging, testing, signing, and release optimizations.
  • Build, verify, and troubleshoot environment-specific application versions.

3. Understanding Application Environments

An environment is a collection of services, infrastructure, and configuration settings used for a particular stage of software development. An Android application may communicate with different backend servers depending on the environment for which it is built.

3.1 Development Environment

The development environment is used by developers while implementing and debugging application features.

  • Connects to local or development backend services.
  • Enables debugging and detailed diagnostic logs.
  • May use mock responses or test accounts.
  • Allows rapid experimentation and feature development.
  • Should not use real production credentials or sensitive customer data unnecessarily.

3.2 Testing Environment

The testing environment is used to verify application behavior before release. It may include a dedicated test backend, test database, automated test services, and controlled test accounts.

  • Supports functional, integration, regression, and acceptance testing.
  • Helps identify bugs before the application reaches users.
  • Uses predictable test data and controlled service configurations.
  • May include automated quality checks and test reporting.
  • Should remain separate from production data and services.

3.3 Staging Environment

Staging is an optional pre-production environment designed to resemble production as closely as practical. It is useful for final acceptance testing, release-candidate verification, and validating integration with production-like services.

3.4 Production Environment

The production environment is used by the released application and real users. It must be configured for stability, security, performance, monitoring, and reliable access to live services.

  • Uses approved production API endpoints.
  • Disables development-only debugging behavior.
  • Uses appropriate release signing and distribution settings.
  • Avoids exposing internal diagnostics or sensitive configuration.
  • Uses controlled logging, monitoring, and crash reporting.

4. Comparing Development, Testing, Staging, and Production

Configuration Development Testing Staging Production
Purpose Build and debug features Verify behavior and quality Validate release readiness Serve real users
Backend Local or development server Dedicated test server Production-like server Live production server
Logging Detailed diagnostic logs Useful test diagnostics Controlled diagnostics Limited, privacy-aware logs
Debugging Enabled for development Enabled where appropriate Restricted Disabled for release builds
Data Sample or developer data Controlled test data Production-like test data Real user data
Signing Debug signing Controlled test signing Release-like signing Approved release signing
Distribution Developer devices Test devices or test tracks Limited release audience Public or approved users

5. Understanding Android Build Types

A build type defines build settings that affect how an application is compiled, packaged, and prepared for distribution. Android Gradle projects commonly include two default build types: debug and release.

5.1 Debug Build Type

The debug build type is intended for development. Android Studio normally configures it for debugging and uses a debug signing configuration.

Typical characteristics include:

  • Debugging support.
  • Development-oriented logging.
  • Optional application ID suffix to install it beside the production app.
  • Test or development-specific configuration values.
  • Potentially different dependencies from the release build.

5.2 Release Build Type

The release build type is intended for distribution. It should be tested carefully and configured for security, performance, and reliable operation.

Typical characteristics include:

  • Debugging disabled.
  • Release signing configuration.
  • Optional code shrinking and obfuscation.
  • Production service endpoints.
  • Limited diagnostic logging and controlled crash reporting.

A release build is not automatically production-ready merely because its build type is named release. Its endpoint selection, signing, security settings, dependencies, and behavior still require verification.

6. Configuring Debug and Release Build Types

Build types are configured in the Android app module's build.gradle.kts file. The following example illustrates a debug build with a separate application ID and a release build with code shrinking enabled.

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    namespace = "com.example.myapp"
    compileSdk = 36

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 23
        targetSdk = 36
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-debug"
            isDebuggable = true
        }

        getByName("release") {
            isDebuggable = false
            isMinifyEnabled = true
            isShrinkResources = true

            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

Note: The SDK values are illustrative. Use SDK and plugin versions appropriate for the project. Resource shrinking is generally used with code shrinking, and the release build should be tested with its final configuration.

7. Understanding Product Flavors

Product flavors define different editions or environment-specific versions of an application. They can provide different application identifiers, resources, configuration values, and feature selections.

For example, a project may define:

  • dev: Connects to development services.
  • staging: Connects to pre-production services.
  • prod: Connects to production services.

These are product flavors, while debug and release are build types. Gradle combines a flavor with a build type to create a build variant.

7.1 Product Flavor Configuration

android {
    flavorDimensions += "environment"

    productFlavors {
        create("dev") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
            versionNameSuffix = "-dev"
        }

        create("staging") {
            dimension = "environment"
            applicationIdSuffix = ".staging"
            versionNameSuffix = "-staging"
        }

        create("prod") {
            dimension = "environment"
        }
    }
}

In this example, the production flavor retains the base application ID, while development and staging variants use suffixes. This allows different versions to be installed together on a device when their application IDs are unique.

8. Understanding Build Variants

A build variant is the combination of a product flavor and a build type. Gradle uses the combined configuration to produce a specific version of the application.

With three flavors—dev, staging, and prod—and two build types—debug and release—Gradle can generate variants such as:

Build Variant Purpose
devDebug Development build with debugging enabled.
devRelease Release-type build using development environment settings, useful only if deliberately required.
stagingDebug Debuggable build connected to staging services.
stagingRelease Release-like build for pre-production verification.
prodDebug Debuggable build configured for production services; use cautiously to avoid accidental production changes.
prodRelease Production-configured release build intended for distribution after verification.

Not every possible variant needs to be used or distributed. A team should choose variants that support its actual workflow and avoid exposing dangerous combinations unnecessarily.

9. Managing Environment-Specific API URLs

Applications often need different backend URLs in different environments. For example, development may use a development API, while production uses the live service.

One approach is to define a build configuration field for each product flavor.

android {
    flavorDimensions += "environment"

    productFlavors {
        create("dev") {
            dimension = "environment"
            buildConfigField(
                "String",
                "BASE_URL",
                "\"https://dev-api.example.com/\""
            )
        }

        create("staging") {
            dimension = "environment"
            buildConfigField(
                "String",
                "BASE_URL",
                "\"https://staging-api.example.com/\""
            )
        }

        create("prod") {
            dimension = "environment"
            buildConfigField(
                "String",
                "BASE_URL",
                "\"https://api.example.com/\""
            )
        }
    }

    buildFeatures {
        buildConfig = true
    }
}

The hostnames above are examples and must be replaced with the actual service endpoints. The quoted value is a Java string literal, which is why the URL is escaped inside the Gradle string.

9.1 Accessing the Configuration Value

val baseUrl = BuildConfig.BASE_URL

The generated BuildConfig class exposes build configuration values to application code. Configure it according to the project's namespace and build setup.

Security note: A value placed in BuildConfig is packaged into the application and can be inspected. Do not store private API keys, passwords, signing credentials, or other secrets there. Public service URLs are generally acceptable because endpoints are not secrets by themselves.

10. Using Source Sets for Environment-Specific Code

Source sets allow developers to place code and resources in directories that are included only in particular build types, product flavors, or build variants.

10.1 Common Source Set Structure

app/
└── src/
    ├── main/
    │   ├── java/
    │   ├── res/
    │   └── AndroidManifest.xml
    ├── dev/
    │   ├── java/
    │   └── res/
    ├── staging/
    │   ├── java/
    │   └── res/
    ├── prod/
    │   ├── java/
    │   └── res/
    ├── debug/
    │   └── java/
    └── release/
        └── java/

The main source set contains code shared by all variants. Flavor-specific and build-type-specific source sets provide additional code or resources for the relevant builds.

10.2 Example Use Cases

  • Display a development banner only in development builds.
  • Provide different application names or icons for separate editions.
  • Include development-only diagnostic tools in a debug source set.
  • Use different resource values for staging and production.
  • Supply different manifest declarations when required by a particular variant.

Avoid duplicating large amounts of code between source sets. Prefer shared implementations with small, well-defined configuration differences whenever possible.

11. Using Environment-Specific Resources

Resources can also vary by product flavor or build type. This is useful for branding, labels, icons, and other values that should differ between environments.

For example, a development build might display an application label such as MyApp Dev, while the production build displays MyApp.

One approach is to define a resource file under each flavor's res/values directory:

app/src/dev/res/values/strings.xml
app/src/staging/res/values/strings.xml
app/src/prod/res/values/strings.xml

Each file can define the same resource name with a different value:

<resources>
    <string name="app_name">MyApp Dev</string>
</resources>

Use the appropriate value in each flavor. Gradle combines resources from active source sets according to its source-set priority rules. Ensure each selected variant resolves to the intended resource value.

12. Managing Dependencies by Build Type

Some libraries are needed only in a particular build type. For example, a development logging library may be useful during debugging but unnecessary in production.

dependencies {
    implementation("androidx.core:core-ktx:1.15.0")

    debugImplementation("com.example:debug-tools:1.0.0")

    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.2.1")
}

The dependency coordinates above are illustrative. Select compatible versions for the project, and use libraries from trusted repositories.

  • implementation adds a dependency to the main application implementation.
  • debugImplementation adds a dependency to debug variants.
  • releaseImplementation adds a dependency to release variants when needed.
  • testImplementation adds dependencies for local unit tests.
  • androidTestImplementation adds dependencies for instrumented tests.

Use variant-specific dependencies to reduce unnecessary release code and keep development-only tools out of production builds. Review the dependency tree and final packaged application when security or size is important.

13. Managing Manifest Placeholders

Manifest placeholders allow Gradle configuration values to be inserted into the manifest during the build. They are useful when a component or manifest entry requires a value that changes between environments.

13.1 Define a Placeholder

android {
    defaultConfig {
        manifestPlaceholders["redirectScheme"] = "myapp"
    }

    productFlavors {
        create("dev") {
            manifestPlaceholders["redirectHost"] = "dev.example.com"
        }

        create("prod") {
            manifestPlaceholders["redirectHost"] = "example.com"
        }
    }
}

13.2 Use a Placeholder in the 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="${redirectScheme}"
            android:host="${redirectHost}" />
    </intent-filter>
</activity>

This example illustrates environment-specific deep-link configuration. If the activity is externally accessible, validate incoming intents carefully and protect sensitive operations. A deep-link filter is not an authentication mechanism.

14. Protecting Secrets and Sensitive Configuration

Applications may need credentials to access third-party services, but values packaged inside an Android application should not be treated as secret. APK and App Bundle contents can be inspected, and obfuscation does not make embedded credentials reliably confidential.

14.1 Do Not Hardcode Private Credentials

Avoid placing the following information directly in source code or client-side build configuration:

  • Private API keys with unrestricted server-side privileges.
  • Database passwords.
  • Production administrator credentials.
  • Private signing keys or keystore passwords.
  • Long-lived service tokens that grant privileged access.

14.2 Safer Approaches

  • Keep server-side secrets on a trusted backend.
  • Use short-lived tokens and appropriate authentication flows.
  • Restrict client API keys to the necessary APIs and application identity where the provider supports such restrictions.
  • Use local untracked configuration files for developer-specific settings when appropriate, while remembering that values compiled into the app are still extractable.
  • Store signing credentials in an approved CI/CD secret store or secure local environment.
  • Rotate credentials if they are accidentally committed or distributed.

A file such as local.properties can help manage local build settings, but it is not a secure vault and must not be relied on to protect secrets that are ultimately packaged into the application.

15. Configuring Logging for Different Environments

Logging is important during development and testing, but production logs must be controlled to avoid exposing sensitive data or creating unnecessary overhead.

15.1 Development Logging

  • Log useful debugging details.
  • Record errors and diagnostic information.
  • Use test data whenever possible.
  • Avoid logging passwords, access tokens, personal information, or sensitive request bodies.

15.2 Production Logging

  • Remove or disable verbose development-only logs.
  • Keep important error and operational information where appropriate.
  • Redact sensitive values from diagnostics.
  • Use approved crash reporting and monitoring services if needed.
  • Review data collection and retention requirements before shipping.

15.3 Example Logging Wrapper

object AppLogger {
    fun debug(message: String) {
        if (BuildConfig.DEBUG) {
            android.util.Log.d("MyApp", message)
        }
    }

    fun error(message: String, throwable: Throwable? = null) {
        android.util.Log.e("MyApp", message, throwable)
    }
}

This simple example conditionally enables debug messages. In a production application, also review whether error messages or throwable details could contain sensitive information. Consider a dedicated logging abstraction if the app needs multiple logging destinations or environment-specific behavior.

16. Configuring Signing for Test and Production Builds

Android packages must be signed before installation or distribution. Debug builds normally use a debug signing configuration created by the development tools. Production releases require a controlled signing process.

16.1 Debug Signing

Android Studio normally creates or uses a debug keystore automatically. It is intended for local development and testing, not as a replacement for the application's approved release-signing process.

16.2 Release Signing

Release signing should be managed securely and consistently. Do not commit private keystores or passwords to a public repository.

  • Store credentials in a secure local or CI/CD environment.
  • Restrict access to release-signing credentials.
  • Verify the signing configuration before publishing.
  • Follow the application's distribution and app-signing requirements.
  • Protect backup copies and document authorized release procedures.

16.3 Example Release Signing Configuration Pattern

android {
    signingConfigs {
        create("release") {
            // Read values from a secure build environment.
            // Do not hardcode passwords or commit keystore files.
            storeFile = file(
                providers.gradleProperty("RELEASE_STORE_FILE").get()
            )
            storePassword =
                providers.gradleProperty("RELEASE_STORE_PASSWORD").get()
            keyAlias =
                providers.gradleProperty("RELEASE_KEY_ALIAS").get()
            keyPassword =
                providers.gradleProperty("RELEASE_KEY_PASSWORD").get()
        }
    }

    buildTypes {
        getByName("release") {
            signingConfig = signingConfigs.getByName("release")
        }
    }
}

This is a configuration pattern rather than a complete drop-in setup. It assumes the relevant Gradle properties are available in the build environment. Avoid placing real secrets in a committed Gradle properties file. For CI/CD, use the platform's secure secret store and carefully control which builds can access signing credentials.

17. Configuring Testing Environments

Testing should verify both application behavior and environment-specific configuration. A successful development build does not guarantee that the production variant will use the correct endpoint, resources, permissions, or dependencies.

17.1 Unit Testing

Unit tests verify small pieces of application logic, such as validation functions, formatting utilities, and business rules. They usually run locally on the JVM.

17.2 Integration Testing

Integration tests verify interactions between components, such as repositories and data sources, or the application and a controlled backend.

17.3 Instrumented Testing

Instrumented tests run on an Android device or emulator. They can validate behavior involving Android framework components, UI interactions, permissions, and device-specific functionality.

17.4 Environment Verification Tests

Check that each variant uses the intended configuration. For example:

  • Development builds use the development API endpoint.
  • Testing builds use test services and controlled test accounts.
  • Staging builds use the intended pre-production services.
  • Production builds use only approved live endpoints.
  • Production builds do not include development-only tools or unintended debug features.

18. Selecting Build Variants in Android Studio

Android Studio provides a Build Variants tool window that allows developers to select the variant to build and run.

  1. Open the Android project in Android Studio.
  2. Open the Build Variants tool window.
  3. Locate the application module.
  4. Select a variant such as devDebug, stagingDebug, or prodRelease.
  5. Wait for Gradle synchronization and project configuration to complete.
  6. Build or run the selected variant.
  7. Verify the app's label, application ID, endpoint, and expected behavior.

Available variants depend on the project's build configuration. Some combinations can be disabled or excluded if they do not make sense for the application.

19. Building Variants from the Command Line

Gradle tasks can build specific variants without requiring the developer to select them through the Android Studio interface.

Examples for a project using the flavor and build-type names from this lesson:

# Build a development debug APK
./gradlew assembleDevDebug

# Build a staging debug APK
./gradlew assembleStagingDebug

# Build a production release APK
./gradlew assembleProdRelease

# Run local unit tests for a selected variant
./gradlew testDevDebugUnitTest

# Run connected instrumented tests for a selected variant
./gradlew connectedDevDebugAndroidTest

On Windows, use gradlew.bat instead of ./gradlew in Command Prompt or PowerShell. Actual task names depend on the module, flavors, build types, and Android Gradle Plugin configuration.

20. Managing Version Names and Application IDs

The application ID uniquely identifies an installed Android application. A development build often uses a suffix so that it can be installed beside the production application.

android {
    defaultConfig {
        applicationId = "com.example.myapp"
        versionCode = 1
        versionName = "1.0"
    }

    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-debug"
        }
    }
}

The resulting debug application ID is com.example.myapp.debug, while the release build retains the base ID unless another configuration changes it.

Before publishing, confirm that the production application ID is correct and stable. Changing the ID can cause the app distribution platform to treat the build as a different application rather than an update to an existing listing.

21. Environment Configuration and Feature Flags

Feature flags determine whether a feature is enabled or disabled. They can help teams test new functionality gradually without maintaining separate codebases.

Examples include:

  • Enabling a new checkout interface for internal testers.
  • Disabling an experimental feature in production.
  • Testing a redesigned profile screen in staging.
  • Enabling a feature for a controlled group of users.

Build-time flags can be configured through product flavors or Gradle fields. Runtime feature flags can be delivered by a backend or configuration service.

Do not treat a client-side feature flag as a security boundary. Sensitive operations and authorization must be enforced on the server, because users may inspect or modify client-side application behavior.

22. Common Configuration Mistakes

Mistake Possible Consequence Recommended Solution
Using production API URLs in development unintentionally Test actions may affect real users or live data. Configure separate endpoints and verify the selected variant.
Hardcoding private credentials Credentials may be extracted from source code or the compiled application. Keep privileged secrets on a trusted server and secure build credentials.
Shipping debug-only dependencies Increased app size or exposure of internal tools. Use appropriate variant-specific dependency configurations.
Leaving debugging enabled in production Unnecessary diagnostic exposure and release configuration problems. Set release debugging appropriately and verify the packaged artifact.
Using one application ID for every installable environment Installing one build may replace another build on the same device. Use intentional application ID suffixes for separate development or staging installations.
Testing only debug builds Release-only crashes, shrinking issues, or configuration errors may go unnoticed. Test the final release configuration before distribution.
Duplicating large amounts of source code Bug fixes may be applied inconsistently across variants. Keep shared logic in common source sets and isolate only genuine differences.
Putting secrets in BuildConfig Values can be extracted from the installed application. Store privileged credentials on a backend and restrict client keys.
Using the wrong signing key Updates may fail to install or publish under the intended app identity. Follow the approved signing and app distribution process.
Ignoring manifest differences Unexpected permissions or component declarations may enter a release build. Inspect the merged manifest for important variants.

23. Best Practices

  • Define a clear purpose for every build type and product flavor.
  • Keep development, testing, staging, and production services separate.
  • Use Gradle configuration and source sets instead of scattered hardcoded environment checks.
  • Use distinct application IDs for variants that must be installed side by side.
  • Keep common business logic in shared source sets or modules.
  • Use variant-specific dependencies for tools that should not be included in production.
  • Do not package private credentials or privileged secrets in the client application.
  • Protect release-signing credentials and restrict access to release pipelines.
  • Verify production endpoints and configuration before every release.
  • Test release builds with code shrinking and resource shrinking enabled when these features are used.
  • Keep logging privacy-aware and remove unnecessary debug output.
  • Use CI/CD automation to build, test, and verify selected variants consistently.
  • Document configuration ownership and release procedures.
  • Review Gradle and Android Studio documentation when updating build tooling.

24. Practical Exercise

Exercise: Configure a sample Android application with development, staging, and production environments.

Requirements

  • Create three product flavors: dev, staging, and prod.
  • Configure debug and release build types.
  • Set a distinct application ID suffix for development and staging.
  • Configure a different API base URL for each flavor.
  • Display an environment label in development and staging builds.
  • Keep development-only logging or tools out of production variants.
  • Configure release signing through a secure build environment.
  • Build and install the development debug variant.
  • Run automated tests against a controlled test environment.
  • Build the production release variant and verify its configuration before distribution.

Expected Results

After completing the exercise, you should be able to generate multiple application variants from one project, identify the environment each variant uses, and verify that development-only settings do not unintentionally enter production.

25. Mini Project: Environment-Aware Task Manager

Create a task-management Android application that retrieves tasks from a backend service.

Project Features

  • Display a list of tasks.
  • Add and update tasks.
  • Retrieve data through an API.
  • Show loading and error states.
  • Provide separate development and production API endpoints.
  • Include unit tests for task-related business logic.
  • Include integration or instrumented tests where appropriate.
  • Configure a release build that does not expose development tools or sensitive diagnostic information.

Suggested Configuration Plan

Variant API Endpoint Expected Behavior
devDebug Development API Debugging enabled and detailed diagnostic support.
stagingDebug Staging API Test features against controlled pre-production services.
stagingRelease Staging API Validate release-like behavior before production.
prodRelease Production API Release-ready configuration for real users.

Document how each variant is built and tested. Confirm that the selected variant uses the correct endpoint before running operations that create, update, or delete data.

26. Interview Questions and Answers

Q1. What is the difference between a build type and a product flavor?

Answer: A build type defines how an application is built, such as debug or release. A product flavor defines a version or edition of the application, such as development, staging, or production.

Q2. What is a build variant?

Answer: A build variant is a specific combination of a product flavor and a build type, along with the configuration and source sets associated with that combination.

Q3. What is the purpose of the debug build?

Answer: It supports development and debugging through debugging settings, diagnostic tools, and a debug signing configuration.

Q4. Why is a release build different from a debug build?

Answer: A release build is prepared for distribution and should use the intended release configuration, signing process, security settings, and performance optimizations.

Q5. What is a product flavor in Android?

Answer: A product flavor defines a version of an application that can have different identifiers, resources, configuration values, or feature selections.

Q6. What is a source set?

Answer: A source set is a collection of code and resources that Gradle includes for a particular build type, product flavor, build variant, or shared configuration.

Q7. How can different API URLs be configured for different environments?

Answer: Developers can use product flavors with generated BuildConfig fields, resources, or another controlled configuration mechanism to provide environment-specific endpoints.

Q8. Why should production credentials not be stored in BuildConfig?

Answer: BuildConfig values are packaged with the application and can be extracted. Privileged secrets should remain on a trusted backend or in secure infrastructure used during builds.

Q9. Why use an application ID suffix?

Answer: It allows development or staging builds to have a different installed application identity, so they can coexist with the production app on the same device.

Q10. What is the purpose of debugImplementation?

Answer: It adds a dependency to debug variants, helping keep development-specific tools out of variants that do not use that configuration.

Q11. Why should release builds be tested?

Answer: Release builds may behave differently because of signing, shrinking, resource optimization, endpoint selection, and other configuration differences.

Q12. What is manifest placeholder configuration?

Answer: Manifest placeholders allow values from Gradle configuration to be inserted into manifest attributes when a variant is built.

Q13. How can environment-specific resources be configured?

Answer: Create resource files in flavor-specific or build-type-specific source sets and provide the appropriate values for each environment.

Q14. What is CI/CD in Android development?

Answer: Continuous integration and continuous delivery or deployment automate tasks such as building variants, running tests, checking quality, signing approved releases, and distributing artifacts.

Q15. What should be checked before publishing a production release?

Answer: Verify the application ID, API endpoints, signing, permissions, release build settings, privacy-sensitive logging, automated test results, and final packaged configuration.

27. Quick Revision Checklist

  • Understand development, testing, staging, and production environments.
  • Know the difference between build types and product flavors.
  • Understand how Gradle creates build variants.
  • Configure environment-specific API endpoints.
  • Use source sets and resources for controlled differences.
  • Manage dependencies at the appropriate variant level.
  • Keep privileged secrets out of the packaged application.
  • Use secure signing practices for production builds.
  • Check application IDs and version information.
  • Test both debug and release variants.
  • Verify endpoints, manifest declarations, and logging before release.
  • Automate repeatable build and test procedures where possible.

28. Conclusion

Managing development, testing, and production configurations is an essential part of professional Android development. Gradle build types control build behavior, product flavors define environment or product differences, and build variants combine these settings to generate distinct application versions.

By using clear configuration boundaries, environment-specific endpoints, source sets, appropriate dependencies, secure signing, and repeatable testing, developers can reduce release mistakes and improve application reliability. Every production release should be built and tested with its final configuration before it is distributed to users.

29. Additional Learning Resources

Previous Next
whatsapp