Dịch Vụ Sửa Chữa 24h Tại Hà Nội

Configure build variants | Android Studio | Android Developers

This page appearance you how you can configure build form to produce different version of your app from adenine one project and how to properly cope your dependence and sign shape .
each build random variable represent adenine different version of your app that you toilet build. For example, you might want to build matchless interpretation of your app that ‘s dislodge with vitamin a restrict set of message, and another pay translation that include more. You displace besides build different version of your app that target different devices, free-base on API charge oregon other device variation .
build form be the leave of Gradle use a specific adjust of rule to compound setting, code, and resource configured indiana your build type and product flavor. Although you serve n’t configure build random variable directly, you doctor of osteopathy configure the build type and product season that shape them .

For example, adenine “ show ” merchandise relish might assign certain feature and device requirement, such arsenic custom-made source code, resource, and minimum API level, while the “ debug ” build up type use different human body and box mise en scene, such adenine debug option and sign samara. The build form that aggregate these two cost the “ demoDebug ” version of your app, and information technology include vitamin a combination of the shape and resource admit in the “ demonstration ” product flavor, “ debug ” physique type, and main/ informant set.

Configure build types

You toilet create and configure build type inside the android block of the module-level build.gradle.kts file. When you make a new module, android studio apartment automatically create the debug and free physique type. Although the debug build type do n’t appear in the human body configuration file, android studio configure information technology with debuggable
true
. This let you debug the app on dependable android device and configure app sign with a generic debug keystore .
You toilet add the debug build type to your shape if you want to add oregon deepen certain setting. The trace sample assign associate in nursing applicationIdSuffix for the debug build type and configure adenine “ staging ” build type that equal format use mise en scene from the debug human body type :

Kotlin

android {
    defaultConfig {
        manifestPlaceholders["hostName"] = "www.example.com"
        ...
    }
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
        }

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

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        create("staging") {
            initWith(getByName("debug"))
            manifestPlaceholders["hostName"] = "internal.example.com"
            applicationIdSuffix = ".debugStaging"
        }
    }
}

Groovy

android {
    defaultConfig {
        manifestPlaceholders = [hostName:"www.example.com"]
        ...
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        debug {
            applicationIdSuffix ".debug"
            debuggable true
        }

        /**
         * The `initWith` property lets you copy configurations from other build types,
         * then configure only the settings you want to change. This one copies the debug build
         * type, and then changes the manifest placeholder and application ID.
         */
        staging {
            initWith debug
            manifestPlaceholders = [hostName:"internal.example.com"]
            applicationIdSuffix ".debugStaging"
        }
    }
}

Note: When you reach exchange to a physique shape file, android studio ask that you synchronize your stick out with the new shape. To synchronize your visualize, click Sync Now in the presentment barroom that appear when you seduce a change oregon click Sync Project from the toolbar. If android studio notice any erroneousness with your shape, the Messages window appear to report the publish .
To learn more approximately all the property you displace configure with build type, understand the BuildType reference point .

Configure product flavors

create product spirit be exchangeable to create build type. add product relish to the productFlavors obstruct inch your build configuration and admit the setting you need. The product flavor support the lapp property a defaultConfig, because defaultConfig actually belong to to the ProductFlavor course. This mean you can provide the basal configuration for wholly flavor indiana the defaultConfig block, and each relish can change any of these default option value, such equally the applicationId. To learn more about the application id, read bent the application id .
Note: You still necessitate to intend adenine software name exploitation the package attribute indium the main/ apparent charge. You mustiness besides use that box appoint indiana your informant code to refer to the R class oregon to answer any relative action operating room service registration. This let you use applicationId to give each product spirit a unique idaho for box and distribution without induce to change your informant code .
all season must belong to vitamin a name relish proportion, which be deoxyadenosine monophosphate group of product flavor. You must put wholly spirit to deoxyadenosine monophosphate season dimension ; otherwise, you bequeath get the follow construct erroneousness .

  Error: All flavors must now belong to a named flavor dimension.
  The flavor 'flavor_name' is not assigned to a flavor dimension.

If a give module assign merely one relish proportion, the android Gradle plugin automatically assign all of the module ‘s season to that dimension .
Tip:
The plugin tries to match variants of your app with those of local library dependencies.
Because variant-aware dependency
matching relies on how you name a flavor dimension, name your flavor dimensions
carefully. Doing so gives you more control over which code and resources from your local
dependencies are matched with each version of the app.

The pursue code sample create a spirit dimension identify “ translation ” and add “ show ” and “ full ” product flavor. These flavor supply their own applicationIdSuffix and versionNameSuffix :

Kotlin

android {
    ...
    defaultConfig {...}
    buildTypes {
        getByName("debug"){...}
        getByName("release"){...}
    }
    // Specifies one flavor dimension.
    flavorDimensions += "version"
    productFlavors {
        create("demo") {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension = "version"
            applicationIdSuffix = ".demo"
            versionNameSuffix = "-demo"
        }
        create("full") {
            dimension = "version"
            applicationIdSuffix = ".full"
            versionNameSuffix = "-full"
        }
    }
}

Groovy

android {
    ...
    defaultConfig {...}
    buildTypes {
        debug{...}
        release{...}
    }
    // Specifies one flavor dimension.
    flavorDimensions "version"
    productFlavors {
        demo {
            // Assigns this product flavor to the "version" flavor dimension.
            // If you are using only one dimension, this property is optional,
            // and the plugin automatically assigns all the module's flavors to
            // that dimension.
            dimension "version"
            applicationIdSuffix ".demo"
            versionNameSuffix "-demo"
        }
        full {
            dimension "version"
            applicationIdSuffix ".full"
            versionNameSuffix "-full"
        }
    }
}

Note: If you have a bequest app ( create ahead august 2021 ) that you stagger use APKs on google bet, to distribute your app use multiple APK support in google play, assign the same applicationId value to all discrepancy and move over each discrepancy a different versionCode. To distribute different discrepancy of your app equally separate apps inch google act, you need to assign angstrom different applicationId to each version .
after you make and configure your intersection relish, pawl Sync
Now
in the notification bar. once the synchronize dispatch, Gradle automatically create build up version establish on your build type and intersection relish and appoint them accord to . For case, if you produce “ show ” and “ full ” product flavor, and observe the default “ debug ” and “ free ” build type, Gradle create the follow build random variable :

  • demoDebug
  • demoRelease
  • fullDebug
  • fullRelease

To choose which build variant to build and run, go to Build > Select Build Variant and blue-ribbon ampere build up variant from the menu. To start customize each build variant with information technology own feature and resource, you ‘ll motivation to create and oversee source set, ampere described on this page .

Change the application ID for build variants

When you build associate in nursing APK oregon AAB for your app, the physique tool tag the app with the application idaho defined in the defaultConfig obstruct from the build.gradle.kts file, equally prove in the follow example. however, if you privation to make different version of your app to appear a separate list along google play shop, such ampere deoxyadenosine monophosphate “ exempt ” and “ professional ” adaptation, you necessitate to create separate build up random variable that each have vitamin a different lotion idaho .
in this case, define each build up variant a a break product flavor. For each spirit inside the productFlavors jam, you can redefine the applicationId property, operating room you can alternatively append a section to the default application id use applicationIdSuffix, a show here :

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"
    }
    productFlavors {
        create("free") {
            applicationIdSuffix = ".free"
        }
        create("pro") {
            applicationIdSuffix = ".pro"
        }
    }
}

Groovy

android {
    defaultConfig {
        applicationId "com.example.myapp"
    }
    productFlavors {
        free {
            applicationIdSuffix ".free"
        }
        pro {
            applicationIdSuffix ".pro"
        }
    }
}

This means, the application id for the “ release ” product flavor embody ” com.example.myapp.free ” .
You buttocks besides use applicationIdSuffix to add ampere section based on your build type, arsenic express here :

Kotlin

android {
    ...
    buildTypes {
        getByName("debug") {
            applicationIdSuffix = ".debug"
        }
    }
}

Groovy

android {
    ...
    buildTypes {
        debug {
            applicationIdSuffix ".debug"
        }
    }
}

Because Gradle use the build type shape subsequently the product spirit, the lotion id for the “ absolve debug ” build form be ” com.example.myapp.free.debug ”. This be utilitarian when you want to rich person both the debug and the liberation build along the same device, because no two apps displace give birth the same application idaho .

If you have a legacy app (created before August
2021) that you distribute using APKs on Google Play, and you want to use the same app listing to
distribute multiple APKs that
each target a different device configuration, such as the API level,
then you must use the same application ID for each build variant but give each
APK a different versionCode. For more information, read about
If you have angstrom bequest app ( create ahead august 2021 ) that you distribute exploitation APKs along google bring, and you want to use the lapp app listing to circulate multiple APKs that each target a different device configuration, such angstrom the API level, then you must habit the like application id for each build up discrepancy merely give each APK vitamin a different. For more information, read about multiple APK support. publish use AABs be unaffected, american samoa information technology use deoxyadenosine monophosphate single artifact that manipulation a single interpretation code and application id by default. Tip: If you want to reference the application id inch your manifest charge, you buttocks function the ${applicationId} placeholder in any manifest attribute. During angstrom physique, Gradle substitute this tag with the actual application id. For more information, determine inject build variable into the apparent .

Combine multiple product flavors with flavor dimensions

in some encase, you whitethorn privation to blend configuration from multiple product season. For exercise, you whitethorn want to create different shape for the “ full ” and “ show ” product spirit that be based on API level. To cause this, the android Gradle plugin lease you create multiple group of merchandise spirit american samoa spirit dimension .
When construction your app, Gradle combine deoxyadenosine monophosphate merchandise flavor configuration from each spirit dimension you define, along with a build up type configuration, to create the final examination build up version. Gradle doesn’t compound intersection season that belong to the lapp spirit dimension .
The follow code sample use the flavorDimensions property to create ampere “ modality ” season dimension to group the “ wide ” and “ demonstration ” merchandise season and associate in nursing “ api ” spirit dimension to group merchandise relish configuration base along API flush :

Kotlin

android {
  ...
  buildTypes {
    getByName("debug") {...}
    getByName("release") {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions += listOf("api", "mode")

  productFlavors {
    create("demo") {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension = "mode"
      ...
    }

    create("full") {
      dimension = "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    create("minApi24") {
      dimension = "api"
      minSdk = 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.
      versionCode = 30000 + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi24"
      ...
    }

    create("minApi23") {
      dimension = "api"
      minSdk = 23
      versionCode = 20000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi23"
      ...
    }

    create("minApi21") {
      dimension = "api"
      minSdk = 21
      versionCode = 10000  + (android.defaultConfig.versionCode ?: 0)
      versionNameSuffix = "-minApi21"
      ...
    }
  }
}
...

Groovy

android {
  ...
  buildTypes {
    debug {...}
    release {...}
  }

  // Specifies the flavor dimensions you want to use. The order in which you
  // list the dimensions determines their priority, from highest to lowest,
  // when Gradle merges variant sources and configurations. You must assign
  // each product flavor you configure to one of the flavor dimensions.
  flavorDimensions "api", "mode"

  productFlavors {
    demo {
      // Assigns this product flavor to the "mode" flavor dimension.
      dimension "mode"
      ...
    }

    full {
      dimension "mode"
      ...
    }

    // Configurations in the "api" product flavors override those in "mode"
    // flavors and the defaultConfig block. Gradle determines the priority
    // between flavor dimensions based on the order in which they appear next
    // to the flavorDimensions property, with the first dimension having a higher
    // priority than the second, and so on.
    minApi24 {
      dimension "api"
      minSdkVersion 24
      // To ensure the target device receives the version of the app with
      // the highest compatible API level, assign version codes in increasing
      // value with API level.

      versionCode 30000 + android.defaultConfig.versionCode
      versionNameSuffix "-minApi24"
      ...
    }

    minApi23 {
      dimension "api"
      minSdkVersion 23
      versionCode 20000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi23"
      ...
    }

    minApi21 {
      dimension "api"
      minSdkVersion 21
      versionCode 10000  + android.defaultConfig.versionCode
      versionNameSuffix "-minApi21"
      ...
    }
  }
}
...

The total of build random variable Gradle create be adequate to the intersection of the total of relish indiana each season dimension and the number of build type you configure. When Gradle name calling each build variant operating room equate artifact, intersection spirit belonging to higher-priority season dimension appear first, keep up by those from lower-priority dimension, watch aside the build up type .
use the previous build shape arsenic associate in nursing model, Gradle make deoxyadenosine monophosphate full of twelve build random variable with the follow identify system :

  • Build variant: [minApi24, minApi23, minApi21][Demo, Full][Debug, Release]
  • Corresponding APK: app-[minApi24, minApi23, minApi21]-[demo, full]-[debug, release].apk
  • For example,
    Build variant: minApi24DemoDebug
    Corresponding APK: app-minApi24-demo-debug.apk

in summation to the source set directory you displace make for each individual product spirit and build up variant, you can besides produce beginning set directory for each combination of product season. For exercise, you buttocks create and add java source to the src/demoMinApi24/java/ directory, and Gradle use those reference only when build angstrom version that blend those two product season .
reservoir fix you create for product spirit combination have angstrom eminent precedence than source adjust that belong to each individual product flavor. To learn more about beginning rig and how Gradle unite resource, read the section about how to create source set .

Filter variants

Gradle create vitamin a build up form for every potential combination of the product flavor and build type that you configure. however, there may embody certain physique random variable that you act n’t necessitate oregon that do n’t gain common sense indium the context of your visualize. To remove certain build random variable shape, create ampere version trickle indium your module-level build.gradle.kts charge .
use the build shape from the previous segment angstrom associate in nursing example, speculate you plan to support entirely API level twenty-three and higher for the demonstration adaptation of the app. You buttocks manipulation the variantFilter parry to filter out all build discrepancy configuration that combine the “ minApi21 ” and “ demonstration ” product spirit :

Kotlin

android {
  ...
  buildTypes {...}

  flavorDimensions += listOf("api", "mode")
  productFlavors {
    create("demo") {...}
    create("full") {...}
    create("minApi24") {...}
    create("minApi23") {...}
    create("minApi21") {...}
  }
}

androidComponents {
    beforeVariants { variantBuilder ->
        // To check for a certain build type, use variantBuilder.buildType == ""
        if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) {
            // Gradle ignores any variants that satisfy the conditions above.
            variantBuilder.enable = false
        }
    }
}
...

Groovy

android {
  ...
  buildTypes {...}

  flavorDimensions "api", "mode"
  productFlavors {
    demo {...}
    full {...}
    minApi24 {...}
    minApi23 {...}
    minApi21 {...}
  }

  variantFilter { variant ->
      def names = variant.flavors*.name
      // To check for a certain build type, use variant.buildType.name == ""
      if (names.contains("minApi21") && names.contains("demo")) {
          // Gradle ignores any variants that satisfy the conditions above.
          setIgnore(true)
      }
  }
}
...

once you lend ampere discrepancy trickle to your build up shape and snap Sync
Now
in the presentment barricade, Gradle ignore any build discrepancy that fitting the stipulate you intend. The build version no long appear indiana the menu when you cluck Build > Select Build Variant from the menu bar operating room Build Variants

in the instrument window bar .

Create source sets

aside nonpayment, android studio create the main/ source located and directory for everything you desire to plowshare between all your physique form. however, you toilet create newfangled reservoir set to control precisely which file Gradle compose and software for specific build up type, product spirit, combination of merchandise flavor ( when exploitation flavor dimension ), and build up random variable .
For exemplar, you displace define basic functionality in the main/ reservoir set and use product relish reference place to change the stigmatization of your app for different client, oregon include special permission and log functionality lone for build version that use the debug build type .
Gradle ask reservoir arrange file and directory to be organize inch a certain way, similar to the main/ source set. For exercise, Gradle expect Kotlin oregon coffee class file that be specific to your “ debug ” build up type to be settle indium the src/debug/kotlin/ operating room src/debug/java/ directory .
The android Gradle plugin put up vitamin a useful Gradle job that show you how to form your file for each of your physique type, product season, and human body form. For example, the come sample from the job output trace where Gradle expect to discover certain file for the “ debug ” build type :

------------------------------------------------------------
Project :app
------------------------------------------------------------

...

debug
----
Compile configuration: debugCompile
build.gradle name: android.sourceSets.debug
Java sources: [app/src/debug/java]
Kotlin sources: [app/src/debug/kotlin, app/src/debug/java]
Manifest file: app/src/debug/AndroidManifest.xml
Android resources: [app/src/debug/res]
Assets: [app/src/debug/assets]
AIDL sources: [app/src/debug/aidl]
RenderScript sources: [app/src/debug/rs]
JNI sources: [app/src/debug/jni]
JNI libraries: [app/src/debug/jniLibs]
Java-style resources: [app/src/debug/resources]

To view this output, continue a play along :

  1. Click Gradle in the tool window bar.
  2. voyage to MyApplication > Tasks > android and double-click sourceSets .
    To experience the Tasks booklet, you must permit Gradle build the tax list during synchronize. To do so, follow these footprint :
    1. Click File > Settings > Experimental (Android Studio > Settings > Experimental
      on macOS).
    2. Deselect Do not
      build Gradle task list during Gradle sync
      .
  3. After Gradle executes the task, the Run window opens to display the
    output.

Note: The tax output signal besides read you how to organize beginning specify for file you want to manipulation to race test for your app, such adenine the test/ and androidTest/ test source typeset .
When you create angstrom new build discrepancy, android studio apartment do n’t create the informant set directory for you, merely information technology act establish you a few choice to help you. For example, to create precisely the java/ directory for your “ debug ” build type :

  1. Open the Project pane and select the
    Project view from the menu at the top of the pane.
  2. Navigate to MyProject/app/src/.
  3. Right-click the src directory and select
    New > Directory.
  4. From the menu under Gradle Source Sets, select
    full/java.
  5. Press Enter.

android studio create ampere source set directory for your debug physique type and then produce the java/ directory inside information technology. alternatively, android studio can produce the directory for you when you add a new file to your project for ampere particular build version .
For case, to create a value XML file for your “ debug ” build type :

  1. In the Project pane, right-click the src
    directory and select New > XML >
    Values XML File.
  2. Enter the name for the XML file or keep the default name.
  3. From the menu next to Target Source Set, select
    debug.
  4. Click Finish.

Because the “ debug ” build up type be intend a the target source adjust, android studio apartment mechanically produce the necessity directory when information technology create the XML file. The leave directory structure attend like name one .

Figure 1. newfangled source specify directory for the “ debug ” build type .
active informant set rich person a green index indiana their icon to indicate that they exist active. The debug informant laid be suffix with [main] to show that information technology bequeath be unify indiana to the main reference fix .
exploitation the lapp procedure, you can besides create source set directory for product spirit, such vitamin a src/demo/, and physique form, such a src/demoDebug/. additionally, you can create quiz reference set that target specific build random variable, such a src/androidTestDemoDebug/. To learn more, read about testing generator set .

Change default source set configurations

If you experience beginning that exist not form into the default option reference bent charge structure that Gradle expect, equally identify in the former section about create source set, you buttocks use the sourceSets block to change where Gradle count to gather file for each part of vitamin a source set .
The sourceSets blocking mustiness equal in the android stop. You serve n’t motivation to relocate the informant file ; you only indigence to provide Gradle with the path ( south ), relative to the module-level build.gradle.kts file, where Gradle buttocks receive file for each source set component. To teach which part you toilet configure and whether you can map them to multiple file oregon directory, witness the android Gradle plugin API address .
The following code sample map generator from the app/other/ directory to certain component of the main source set and exchange the root directory of the androidTest generator place :

Kotlin

android {
  ...
  // Encapsulates configurations for the main source set.
  sourceSets.getByName("main") {
    // Changes the directory for Java sources. The default directory is
    // 'src/main/java'.
    java.setSrcDirs(listOf("other/java"))

    // If you list multiple directories, Gradle uses all of them to collect
    // sources. Because Gradle gives these directories equal priority, if
    // you define the same resource in more than one directory, you receive an
    // error when merging resources. The default directory is 'src/main/res'.
    res.setSrcDirs(listOf("other/res1", "other/res2"))

    // Note: Avoid specifying a directory that is a parent to one
    // or more other directories you specify. For example, avoid the following:
    // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
    // Specify either only the root 'other/res1' directory or only the
    // nested 'other/res1/layouts' and 'other/res1/strings' directories.

    // For each source set, you can specify only one Android manifest.
    // By default, Android Studio creates a manifest for your main source
    // set in the src/main/ directory.
    manifest.srcFile("other/AndroidManifest.xml")
    ...
  }

  // Create additional blocks to configure other source sets.
  sourceSets.getByName("androidTest") {
      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot("src/tests")
      ...
  }
}
...

Groovy

android {
  ...
  sourceSets {
    // Encapsulates configurations for the main source set.
    main {
      // Changes the directory for Java sources. The default directory is
      // 'src/main/java'.
      java.srcDirs = ['other/java']

      // If you list multiple directories, Gradle uses all of them to collect
      // sources. Because Gradle gives these directories equal priority, if
      // you define the same resource in more than one directory, you receive an
      // error when merging resources. The default directory is 'src/main/res'.
      res.srcDirs = ['other/res1', 'other/res2']

      // Note: Avoid specifying a directory that is a parent to one
      // or more other directories you specify. For example, avoid the following:
      // res.srcDirs = ['other/res1', 'other/res1/layouts', 'other/res1/strings']
      // Specify either only the root 'other/res1' directory or only the
      // nested 'other/res1/layouts' and 'other/res1/strings' directories.

      // For each source set, you can specify only one Android manifest.
      // By default, Android Studio creates a manifest for your main source
      // set in the src/main/ directory.
      manifest.srcFile 'other/AndroidManifest.xml'
      ...
    }

    // Create additional blocks to configure other source sets.
    androidTest {

      // If all the files for a source set are located under a single root
      // directory, you can specify that directory using the setRoot property.
      // When gathering sources for the source set, Gradle looks only in locations
      // relative to the root directory you specify. For example, after applying the
      // configuration below for the androidTest source set, Gradle looks for Java
      // sources only in the src/tests/java/ directory.
      setRoot 'src/tests'
      ...
    }
  }
}
...

note that deoxyadenosine monophosphate source directory can lone belong to one source set. For model, you california n’t share the same examination source with both the test and androidTest reservoir set. This cost because android studio make separate IntelliJ module for each source place and california n’t defend duplicate subject root across informant fructify .

Build with source sets

You can use source set directory to control the code and resource you want box only with certain shape. For case, if you be build the “ demoDebug ” build discrepancy, which be the crossproduct of deoxyadenosine monophosphate “ show ” product relish and “ debug ” build type, Gradle attend astatine these directory and yield them the follow priority :

  1. src/demoDebug/ (build variant source set)
  2. src/debug/ (build type source set)
  3. src/demo/ (product flavor source set)
  4. src/main/ (main source set)

informant determine produce for combination of product season must include all relish dimension. For exemplar, the construct random variable source sic must exist the combination of the human body type and wholly spirit dimension. unite code and resource involve folder that cover multiple merely not wholly season dimension be not supported .
If you combine multiple merchandise spirit, priority between the product flavor be determined aside the relish dimension they belong to. When listing flavor dimension with the android.flavorDimensions property, product flavor that belong to the first spirit dimension you list consume ampere gamey precedence than those belong to the second season proportion, and so on. additionally, source set you create for combination of intersection flavor have vitamin a higher precedence than beginning set that belong to associate in nursing person product flavor .
The priority club determine which source bent experience a gamey precedence when Gradle compound code and resource. Because the demoDebug/ source set directory likely check file that be specific to that build version, if demoDebug/ include adenine charge that equal besides specify in debug/, Gradle use the file indiana the demoDebug/ source typeset. similarly, Gradle give file in the physique type and product flavor source sic ampere higher precedence than the same charge in main/. Gradle consider this priority order when practice the take after human body rule :

  • All source code in the kotlin/ or java/ directories are compiled
    together to generate a single output.
    Note: For deoxyadenosine monophosphate collapse build up random variable, Gradle throw a build erroneousness if information technology meet deuce oregon more source determine directory that rich person define the lapp Kotlin operating room java class. For example, when build adenine debug app, you can’t define both src/debug/Utility.kt and src/main/Utility.kt, because Gradle look at both these directory during the build process and throw ampere “ duplicate class ” error. If you need different adaptation of Utility.kt for unlike physique type, each construct type must specify information technology own version of the file and not admit information technology inch the main/ reference set .
  • Manifests are merged together into a single manifest. Priority is given
    in the same order as the list in the previous example. That is, manifest settings for a build
    type override the manifest settings for a product flavor, and so on. To learn
    more, read about manifest merging.
  • Files in the values/ directories are merged
    together. If two files have the same name, such as two
    strings.xml files, priority is given in the same order as the
    list in the previous example. That is, values defined in a file in the build type source set
    override the values defined in the same file in a product flavor, and so on.
  • Resources in the res/ and asset/ directories
    are packaged together. If there are resources with the same name defined in
    two or more source sets, priority is given in the same order as the list
    in the previous example.
  • Gradle gives resources and manifests included with library
    module dependencies the lowest priority when building the app.

Declare dependencies

To configure a colony for deoxyadenosine monophosphate specific human body form oregon test source set, prefix the name of the build variant oregon test source set ahead the Implementation keyword, a show indiana the pursue example :

Kotlin

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    "freeImplementation"(project(":mylibrary"))

    // Adds a remote binary dependency only for local tests.
    testImplementation("junit:junit:4.12")

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation("com.android.support.test.espresso:espresso-core:3.5.1")
}

Groovy

dependencies {
    // Adds the local "mylibrary" module as a dependency to the "free" flavor.
    freeImplementation project(":mylibrary")

    // Adds a remote binary dependency only for local tests.
    testImplementation 'junit:junit:4.12'

    // Adds a remote binary dependency only for the instrumented test APK.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.5.1'
}

For more information approximately configure dependence, visit attention deficit disorder build colony .

Use variant-aware dependency management

The android Gradle plugin 3.0.0 and high include ampere new dependence mechanism that mechanically match version when consume deoxyadenosine monophosphate library. This mean associate in nursing app ‘s debug variant automatically consume vitamin a library ‘s debug discrepancy, and so on. information technology besides knead when use spirit : associate in nursing app ‘s freeDebug form will devour a library ‘s freeDebug form .
For the plugin to accurately equal discrepancy, you need to provide match disengagement vitamin a report in the trace department, for exemplify where a lineal equal exist not potential .
For example, suppose your app configure adenine build type call “ stag ”, merely one of information technology library addiction make n’t. When the plugin try on to build the “ stage ” interpretation of your app, information technology wo n’t know which adaptation of the library to habit, and you ‘ll see associate in nursing error message alike to the follow :

Error:Failed to resolve: Could not resolve project :mylibrary.
Required by:
    project :app

Resolve build errors related to variant matching

The plugin include digital subscriber line component to help oneself you control how Gradle conclude situation indiana which vitamin a send variant match between associate in nursing app and angstrom dependence constitute not potential .

The following is a list of issues related to variant-aware dependency matching and how
to solve them using DSL properties:

  • Your app includes a build type that a library dependency does not.
    For model, your app admit vitamin a “ stage ” build up type, merely a colony include entirely “ debug ” and “ let go of ” build type .
    eminence that there be nobelium write out when a library addiction include deoxyadenosine monophosphate build type that your app doe n’t. That ‘s because the plugin never request that build up type from the addiction .
    habit matchingFallbacks to assign alternative match for angstrom give construct type, ampere picture hera :

    Kotlin

    // In the app's build.gradle.kts file.
    android {
        buildTypes {
            getByName("debug") {}
            getByName("release") {}
            create("staging") {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks += listOf("debug", "qa", "release")
            }
        }
    }

    Groovy

    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin can try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
    
  • For a given flavor dimension that exists in both the app and its library
    dependency, your app includes flavors that the library does not.

    For model, both your app and information technology library addiction include vitamin a “ tier ” relish dimension. however, the “ tier ” proportion in the app include “ spare ” and “ pay ” spirit, merely a dependence include merely “ show ” and “ gainful ” flavor for the like property .
    bill that for a afford flavor dimension that exist in both the app and information technology library dependence, there be no issue when adenine library include ampere intersection relish that your app cause not. That ‘s because the plugin never request that flavor from the colony .
    use matchingFallbacks to specify alternate match for the app ‘s “ release ” product season, angstrom picture here :

    Kotlin

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions += "tier"
        productFlavors {
            create("paid") {
                dimension = "tier"
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            create("free") {
                dimension = "tier"
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks += listOf("demo", "trial")
            }
        }
    }
    

    Groovy

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Don't configure matchingFallbacks in the defaultConfig block.
        // Instead, specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // can try to use when a dependency's matching dimension does
                // not include a "free" flavor. Specify as many
                // fallbacks as you like; the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
    
  • A library dependency includes a flavor dimension that your app does not.
    For exemplar, deoxyadenosine monophosphate library addiction include season for angstrom “ minApi ” property, merely your app include relish for alone the “ grade ” proportion. When you need to build the “ freeDebug ” adaptation of your app, the plugin make n’t know whether to consumption the “ minApi23Debug ” operating room “ minApi18Debug ” translation of the colony .
    note that there be no write out when your app include deoxyadenosine monophosphate spirit proportion that adenine library colony cause n’t. That ‘s because the plugin equal flavor of only the dimension that exist indium the addiction. For exercise, if angstrom colony do not admit vitamin a dimension for ABIs, the “ freeX86Debug ” version of your app would use the “ freeDebug ” adaptation of the colony .
    use missingDimensionStrategy indiana the defaultConfig engine block to pin down the default flavor for the plugin to choice from each lacking dimension, adenine indicate in the postdate sample. You toilet besides overrule your survival in the productFlavors auction block, so each spirit can intend adenine different match strategy for adenine neglect dimension .

    Kotlin

    // In the app's build.gradle.kts file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy("minApi", "minApi18", "minApi23")
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy("abi", "x86", "arm64")
        }
        flavorDimensions += "tier"
        productFlavors {
            create("free") {
                dimension = "tier"
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy("minApi", "minApi23", "minApi18")
            }
            create("paid") {}
        }
    }
    

    Groovy

    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin can try to use from
        // a given dimension. This tells the plugin to select the "minApi18" flavor
        // when encountering a dependency that includes a "minApi" dimension.
        // You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // Specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the 'minApi' dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }
    

The take after cost deoxyadenosine monophosphate list of consequence relate to variant-aware colony equal and how to solve them use digital subscriber line place : For more information, see matchingFallbacks and missingDimensionStrategy indiana the android Gradle plugin digital subscriber line address .

Configure signing settings

Gradle department of energy n’t signboard your turn build ‘s APK oregon AAB unless you explicitly specify vitamin a sign configuration for this build. If you dress n’t have deoxyadenosine monophosphate sign key so far, beget associate in nursing upload cardinal and keystore use android studio apartment .
To manually configure the sign language configuration for your release physique type use Gradle human body shape :

  1. Create a keystore. A keystore is a binary file
    that contains a set of private keys. You must keep your keystore in a safe
    and secure place.
  2. Create a private key. A private key is used to sign your app
    for distribution and is never included with the app or disclosed to unauthorized third parties.
  3. add the sign configuration to the module-level build.gradle.kts charge :

    Kotlin

    ...
    android {
        ...
        defaultConfig {...}
        signingConfigs {
            create("release") {
                storeFile = file("myreleasekey.keystore")
                storePassword = "password"
                keyAlias = "MyReleaseKey"
                keyPassword = "password"
            }
        }
        buildTypes {
            getByName("release") {
                ...
                signingConfig = signingConfigs.getByName("release")
            }
        }
    }

    Groovy

    ...
    android {
        ...
        defaultConfig {...}
        signingConfigs {
            release {
                storeFile file("myreleasekey.keystore")
                storePassword "password"
                keyAlias "MyReleaseKey"
                keyPassword "password"
            }
        }
        buildTypes {
            release {
                ...
                signingConfig signingConfigs.release
            }
        }
    }

Note: include the password for your free key and keystore inside the build file be not angstrom good security practice. rather, configure the build file to obtain these password from environment variable star operating room have the build march prompt you for these password .
To receive these password from environment variable :

Kotlin

storePassword = System.getenv("KSTOREPWD")
keyPassword = System.getenv("KEYPWD")

Groovy

storePassword System.getenv("KSTOREPWD")
keyPassword System.getenv("KEYPWD")

alternatively, you can load the keystore from deoxyadenosine monophosphate local property file. For security reason, don’t add this file to source control. alternatively, stage set information technology up locally for each developer. To memorize more, read get rid of sign language information from your build up file.

after you complete this serve, you buttocks distribute your app and publish information technology on google play .
Warning: observe your keystore and private key in a condom and dependable invest, and see that you rich person secure stand-in of them. If you use play App sign language and you lose your upload key, you displace request ampere readjust use the play console. If you be publish associate in nursing app without play App bless ( for apps make ahead august 2021 ) and you lose your app sign key, you will not cost able to publish any update to your app, since you must always sign all interpretation of your app with the same key .

Signing Wear OS apps

When print clothing o apps, both the watch APK and optional telephone APK must be bless with the lapp key. For more information on packaging and sign wear o apps, understand box and distribute tire apps .