Gradle und das Android-Plug-in für Gradle bieten eine flexible Möglichkeit, Ihre Android-App oder ‑Bibliothek zu kompilieren, zu erstellen und zu verpacken. Auf dieser Seite finden Sie einige nützliche Tipps und Konfigurationen, mit denen Sie jeden Build optimal nutzen können. Informationen dazu, wie Sie Ihre Builds beschleunigen können, finden Sie unter Build-Geschwindigkeit optimieren.
Wenn Sie Gradle noch nicht kennen, lesen Sie den Artikel Build konfigurieren, um sich mit den Grundlagen vertraut zu machen. Weitere Informationen zu den auf dieser Seite verwendeten Properties finden Sie in der DSL-Referenzdokumentation des Android-Plug-ins.
Projekte und Quellen verwalten
Hier sind einige Konfigurationen zum Verwalten der Module und ihrer Quellen in Ihrem Projekt. Weitere Informationen zum Erstellen und Verwalten von Projekten und Modulen finden Sie in der Projektübersicht.
Standardkonfigurationen für Quellgruppen ändern
Mit dem Block
sourceSets
in der Datei build.gradle
auf Modulebene können Sie ändern, wo Gradle nach Dateien für jede Komponente eines Quellsatzes sucht.
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'] // When you list multiple directories, Gradle uses all of them to collect // sources. You should avoid specifying a directory which is a parent to one // or more other directories you specify. res.srcDirs = ['other/res1', 'other/res2'] // For each source set, you can specify only one Android manifest. // The following points Gradle to a different manifest for this source set. 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' ... } } } ...
Kotlin
android { ... sourceSets { // Encapsulates configurations for the main source set. getByName("main") { // Changes the directory for Java sources. The default directory is // 'src/main/java'. java.setSrcDirs("other/java") // When you list multiple directories, Gradle uses all of them to collect // sources. You should avoid specifying a directory which is a parent to one // or more other directories you specify. res.setSrcDirs("other/res1", "other/res2") // For each source set, you can specify only one Android manifest. // The following points Gradle to a different manifest for this source set. 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") ... } } } ...
Bibliotheken und Abhängigkeiten verwalten
Gradle bietet einen robusten Mechanismus zum Verwalten von Abhängigkeiten, unabhängig davon, ob es sich um Remotebibliotheken oder lokale Bibliotheksmodule handelt.
Mit Abhängigkeitskonfigurationen auf bestimmte Builds abzielen
Wenn eine Abhängigkeit nur für eine bestimmte Buildvariante oder Testquellengruppe gelten soll, geben Sie den Namen der Abhängigkeitskonfiguration in Großbuchstaben ein und fügen Sie davor den Namen der Buildvariante oder Testquellengruppe ein.
Groovy
android {...} // Creates Gradle dependency configurations to use in the dependencies block. configurations { // For variants that combine a product flavor and build type, you need to // intitialize a placeholder for its dependency configuration. freeDebugRuntimeOnly{} ... } dependencies { // Adds an implementation dependency only to the "free" product flavor. freeImplementation 'com.google.firebase:firebase-ads:21.5.1' // Adds a runtimeOnly dependency only to the "freeDebug" build variant. freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar']) // 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.6.1' }
Kotlin
android {...} dependencies { // Use ""() notation for custom flavors and build types // Adds an implementation dependency only to the "free" product flavor. "freeImplementation"("com.google.firebase:firebase-ads:21.5.1") // Adds a runtimeOnly dependency only to the "freeDebug" build variant. "freeDebugRuntimeOnly"(fileTree("dir" to "libs", "include" to "*.jar")) // 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.6.1") }
Verschiedene Versionen Ihrer App erstellen
Mit Gradle und dem Android-Plug-in können Sie verschiedene Versionen Ihrer App aus einem einzigen Modul erstellen, indem Sie Build-Varianten konfigurieren.
Dynamische Versionscodes konfigurieren
Wenn Gradle standardmäßig APKs für Ihr Projekt generiert, enthält jedes APK dieselben Versionsinformationen wie in der build.gradle
-Datei auf Modulebene angegeben.
Da im Google Play Store keine mehrere APKs für dieselbe App mit denselben Versionsinformationen zulässig sind, muss jedes APK einen eindeutigen Versionscode haben, bevor Sie es in den Play Store hochladen.
Sie können dies mit benutzerdefinierter Build-Logik tun, die jedem APK zum Zeitpunkt des Builds einen anderen Versionscode zuweist. Wenn Sie beispielsweise separate APKs für jedes ABI erstellen, sieht die automatische APK-Versionierung in etwa so aus:
Cool
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // Map for the version code that gives each ABI a value. ext.abiCodes = ['armeabi-v7a':1, mips:2, x86:3] // For per-density APKs, create a similar map like this: // ext.densityCodes = ['hdpi': 1, 'xhdpi': 2, 'xxhdpi': 3, 'xxxhdpi': 4] import com.android.build.OutputFile // For each APK output variant, override versionCode with a combination of // ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. android.applicationVariants.all { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.each { output -> // Stores the value of ext.abiCodes that is associated with the ABI for this variant. def baseAbiVersionCode = // Determines the ABI for this variant and returns the mapped value. project.ext.abiCodes.get(output.getFilter(OutputFile.ABI)) // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code does not override the version code for universal APKs. // However, because we want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiVersionCode != null) { // Assigns the new version code to versionCodeOverride, which changes the version code // for only the output APK, not for the variant itself. Skipping this step simply // causes Gradle to use the value of variant.versionCode for the APK. output.versionCodeOverride = baseAbiVersionCode * 1000 + variant.versionCode } } }
Kotlin
android { ... defaultConfig { ... versionCode = 4 } splits { ... } } // Map for the version code that gives each ABI a value. val abiCodes = mapOf("armeabi-v7a" to 1, "mips" to 2, "x86" to 3) // For per-density APKs, create a similar map like this: // val densityCodes = mapOf("hdpi" to 1, "xhdpi" to 2, "xxhdpi" to 3, "xxxhdpi" to 4) import com.android.build.api.variant.FilterConfiguration.FilterType.* // For each APK output variant, override versionCode with a combination of // abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode // is equal to defaultConfig.versionCode. If you configure product flavors that // define their own versionCode, variant.versionCode uses that value instead. androidComponents { onVariants { variant -> // Assigns a different version code for each output APK // other than the universal APK. variant.outputs.forEach { output -> val name = output.filters.find { it.filterType == ABI }?.identifier // Stores the value of abiCodes that is associated with the ABI for this variant. val baseAbiCode = abiCodes[name] // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes, // the following code does not override the version code for universal APKs. // However, because we want universal APKs to have the lowest version code, // this outcome is desirable. if (baseAbiCode != null) { // Assigns the new version code to output.versionCode, which changes the version code // for only the output APK, not for the variant itself. output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0)) } } } }
Mehrere Produktvarianten kombinieren
In einigen Fällen möchten Sie möglicherweise Konfigurationen aus mehreren Produktvarianten kombinieren. Dazu können Sie mit dem Android-Plug-in für Gradle Gruppen von Produktvarianten erstellen, die als Variantendimensionen bezeichnet werden.
Im folgenden Codebeispiel wird die Property
flavorDimensions
verwendet, um eine Variante „Modus“ zu erstellen, mit der die Produktvarianten „Vollständig“ und „Demo“ gruppiert werden, und eine Variante „api“, mit der die Konfigurationen der Produktvarianten basierend auf der API-Ebene gruppiert werden. Gradle kombiniert dann die Produktvarianten aus der Dimension „mode“ mit denen der Dimension „api“.
Cool
android { ... buildTypes { debug {...} release {...} } // Specifies the flavor dimensions you want to use. The order in which you // list each dimension determines its 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 above--the first dimension has 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. To learn more about assigning version codes to // support app updates and uploading to Google Play, read Multiple APK Support 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" ... } } } ...
Kotlin
android { ... buildTypes { getByName("debug") {...} getByName("release") {...} } // Specifies the flavor dimensions you want to use. The order in which you // list each dimension determines its 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 above--the first dimension has a higher // priority than the second, and so on. create("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. To learn more about assigning version codes to // support app updates and uploading to Google Play, read Multiple APK Support versionCode = 30000 + android.defaultConfig.versionCode versionNameSuffix = "-minApi24" ... } create("minApi23") { dimension = "api" minSdkVersion(23) versionCode = 20000 + android.defaultConfig.versionCode versionNameSuffix = "-minApi23" ... } create("minApi21") { dimension = "api" minSdkVersion(21) versionCode = 10000 + android.defaultConfig.versionCode versionNameSuffix = "-minApi21" ... } } } ...
Varianten filtern
Sie können unerwünschte Buildvarianten herausfiltern, indem Sie in der build.gradle
-Datei des Moduls den Block
variantFilter
verwenden. Im folgenden Beispielcode wird Gradle angewiesen, keine Varianten zu erstellen, die die Produktvarianten „minApi21“ und „demo“ kombinieren:
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 == "<buildType>" if (names.contains("minApi21") && names.contains("demo")) { // Gradle ignores any variants that satisfy the conditions above. setIgnore(true) } } } ...
Kotlin
android { ... buildTypes {...} flavorDimensions "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 == "<buildType>" if (variantBuilder.productFlavors.containsAll(listOf("api" to "minApi21", "mode" to "demo"))) { // Gradle ignores any variants that satisfy the conditions above. variantBuilder.enabled = false } } } ...
App testen
Weitere Informationen zum Ausführen lokaler und integrierter Einheitentests finden Sie unter App testen.
Lint-Optionen konfigurieren
Sie können bestimmte Lint-Optionen mithilfe des Blocks
lintOptions
in der build.gradle
-Datei auf Modulebene konfigurieren. Weitere Informationen zur Verwendung von Lint für Ihr Android-Projekt finden Sie unter Code mit Lint verbessern.
Cool
android { ... lintOptions { // Turns off checks for the issue IDs you specify. disable 'TypographyFractions','TypographyQuotes' // Turns on checks for the issue IDs you specify. These checks are in // addition to the default lint checks. enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' // To enable checks for only a subset of issue IDs and ignore all others, // list the issue IDs with the 'check' property instead. This property overrides // any issue IDs you enable or disable using the properties above. checkOnly 'NewApi', 'InlinedApi' // If set to true, turns off analysis progress reporting by lint. quiet true // if set to true (default), stops the build if errors are found. abortOnError false // if true, only report errors. ignoreWarnings true } } ...
Kotlin
android { ... lintOptions { // Turns off checks for the issue IDs you specify. disable("TypographyFractions") disable("TypographyQuotes") // Turns on checks for the issue IDs you specify. These checks are in // addition to the default lint checks. enable("RtlHardcoded") enable("RtlCompat") enable("RtlEnabled") // To enable checks for only a subset of issue IDs and ignore all others, // list the issue IDs with the 'check' property instead. This property overrides // any issue IDs you enable or disable using the properties above. checkOnly("NewApi", "InlinedApi") // If set to true, turns off analysis progress reporting by lint. quiet = true // if set to true (default), stops the build if errors are found. abortOnError = false // if true, only report errors. ignoreWarnings = true } } ...
Manifesteinstellungen für die Instrumentierung konfigurieren
Wenn Gradle Ihr Test-APK erstellt, generiert es automatisch die Datei AndroidManifest.xml
und konfiguriert sie mit dem Knoten <instrumentation>
. Sie können einige der Einstellungen für diesen Knoten ändern, indem Sie entweder eine weitere Manifestdatei im Test-Quellsatz erstellen oder die build.gradle
-Datei auf Modulebene konfigurieren, wie im folgenden Codebeispiel gezeigt.
Cool
android { ... // Each product flavor you configure can override properties in the // defaultConfig block. To learn more, go to Configure Product Flavors. defaultConfig { ... // Specifies the application ID for the test APK. testApplicationId "com.test.foo" // Specifies the fully-qualified class name of the test instrumentation runner. testInstrumentationRunner "android.test.InstrumentationTestRunner" // If set to 'true', enables the instrumentation class to start and stop profiling. // If set to false (default), profiling occurs the entire time the instrumentation // class is running. testHandleProfiling true // If set to 'true', indicates that the Android system should run the instrumentation // class as a functional test. The default value is 'false' testFunctionalTest true } } ...
Kotlin
android { ... // Each product flavor you configure can override properties in the // defaultConfig block. To learn more, go to Configure Product Flavors. defaultConfig { ... // Specifies the application ID for the test APK. testApplicationId = "com.test.foo" // Specifies the fully-qualified class name of the test instrumentation runner. testInstrumentationRunner = "android.test.InstrumentationTestRunner" // If set to 'true', enables the instrumentation class to start and stop profiling. // If set to false (default), profiling occurs the entire time the instrumentation // class is running. testHandleProfiling = true // If set to 'true', indicates that the Android system should run the instrumentation // class as a functional test. The default value is 'false' testFunctionalTest = true } } ...
Test-Build-Typ ändern
Standardmäßig werden alle Tests mit dem Debug-Buildtyp ausgeführt. Sie können dies mithilfe der testBuildType
-Eigenschaft in der build.gradle
-Datei auf Modulebene in einen anderen Buildtyp ändern. Wenn Sie Ihre Tests beispielsweise mit dem Buildtyp „Staging“ ausführen möchten, bearbeiten Sie die Datei wie im folgenden Snippet gezeigt.
Groovy
android { ... testBuildType "staging" }
Kotlin
android { ... testBuildType "staging" }
Gradle-Testoptionen konfigurieren
Wenn Sie Optionen angeben möchten, die die Ausführung aller Tests durch Gradle ändern, konfigurieren Sie den Block
testOptions
auf Modulebene in build.gradle
.
Groovy
android { ... // Encapsulates options for running tests. testOptions { // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports // in the path_to_your_project/module_name/build/outputs/reports/ directory. // '$rootDir' sets the path relative to the root directory of the current project. reportDir "$rootDir/test-reports" // Changes the directory where Gradle saves test results. By default, Gradle saves test results // in the path_to_your_project/module_name/build/outputs/test-results/ directory. // '$rootDir' sets the path relative to the root directory of the current project. resultsDir "$rootDir/test-results" } }
Kotlin
android { ... // Encapsulates options for running tests. testOptions { // Changes the directory where Gradle saves test reports. By default, Gradle saves test reports // in the path_to_your_project/module_name/build/outputs/reports/ directory. // '$rootDir' sets the path relative to the root directory of the current project. reportDir "$rootDir/test-reports" // Changes the directory where Gradle saves test results. By default, Gradle saves test results // in the path_to_your_project/module_name/build/outputs/test-results/ directory. // '$rootDir' sets the path relative to the root directory of the current project. resultsDir "$rootDir/test-results" } }
Wenn Sie Optionen nur für lokale Einheitentests angeben möchten, konfigurieren Sie den Block
testOptions.unitTests
.
Groovy
android { ... testOptions { ... // Encapsulates options for local unit tests. unitTests { // By default, local unit tests throw an exception any time the code you are testing tries to access // Android platform APIs (unless you mock Android dependencies yourself or with a testing // framework like Mockito). However, you can enable the following property so that the test // returns either null or zero when accessing platform APIs, rather than throwing an exception. returnDefaultValues true // Encapsulates options for controlling how Gradle executes local unit tests. For a list // of all the options you can specify, read Gradle's reference documentation. all { // Sets JVM argument(s) for the test JVM(s). jvmArgs '-XX:MaxPermSize=256m' // You can also check the task name to apply options to only the tests you specify. if (it.name == 'testDebugUnitTest') { systemProperty 'debug', 'true' } } } } }
Kotlin
android { ... testOptions { ... // Encapsulates options for local unit tests. unitTests { // By default, local unit tests throw an exception any time the code you are testing tries to access // Android platform APIs (unless you mock Android dependencies yourself or with a testing // framework like Mockito). However, you can enable the following property so that the test // returns either null or zero when accessing platform APIs, rather than throwing an exception. returnDefaultValues true // Encapsulates options for controlling how Gradle executes local unit tests. For a list // of all the options you can specify, read Gradle's reference documentation. all { // Sets JVM argument(s) for the test JVM(s). jvmArgs '-XX:MaxPermSize=256m' // You can also check the task name to apply options to only the tests you specify. if (it.name == 'testDebugUnitTest') { systemProperty 'debug', 'true' } } } } }
Build optimieren
In diesem Abschnitt finden Sie einige Konfigurationen, mit denen Sie vollständige und inkrementelle Builds beschleunigen können. Weitere Informationen finden Sie unter Build-Geschwindigkeit optimieren.
Code verkleinern
Android Studio verwendet R8, das ProGuard-Regeldateien nutzt, um Ihren Code zu verkleinern. Für neue Projekte verwendet Android Studio eine Standardeinstellungsdatei (proguard-android.txt
) aus dem tools/proguard/folder
des Android SDK. Wenn Sie den Code noch weiter komprimieren möchten, verwenden Sie die proguard-android-optimize.txt
-Datei am selben Speicherort.
Groovy
android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } ... } ...
Kotlin
android { buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } ... } ...
Wenn Sie Regeln hinzufügen möchten, die für jede Buildvariante spezifisch sind, konfigurieren Sie für jede Variante eine zusätzliche
proguardFiles
-Eigenschaft. Im folgenden Beispiel wird beispielsweise flavor2-rules.pro
zu „flavor2“ hinzugefügt. Jetzt werden für die Releaseversion von „flavor2“ alle drei Regeldateien verwendet, da auch die aus dem Release-Block angewendet werden.
Groovy
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { flavor1 { ... } flavor2 { proguardFile 'flavor2-rules.pro' } } } ...
Kotlin
android { ... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } productFlavors { flavor1 { ... } flavor2 { proguardFile 'flavor2-rules.pro' } } } ...
App veröffentlichen
Weitere Informationen zum Veröffentlichen Ihrer App bei Google Play finden Sie unter App veröffentlichen.
App signieren
In Android Studio können Sie die Signatur für Release-Builds über die Benutzeroberfläche ganz einfach konfigurieren. Sie können den Block
signingConfigs
aber auch manuell in der Datei build.gradle
Ihres Moduls konfigurieren:
Groovy
android { ... defaultConfig { ... } // Encapsulates signing configurations. signingConfigs { // Creates a signing configuration called "release". release { // Specifies the path to your keystore file. storeFile file("my-release-key.jks") // Specifies the password for your keystore. storePassword "password" // Specifies the identifying name for your key. keyAlias "my-alias" // Specifies the password for your key. keyPassword "password" } } buildTypes { release { // Adds the "release" signing configuration to the release build type. signingConfig signingConfigs.release ... } } } ...
Kotlin
android { ... defaultConfig { ... } // Encapsulates signing configurations. signingConfigs { // Creates a signing configuration called "release". release { // Specifies the path to your keystore file. storeFile file("my-release-key.jks") // Specifies the password for your keystore. storePassword "password" // Specifies the identifying name for your key. keyAlias "my-alias" // Specifies the password for your key. keyPassword "password" } } buildTypes { release { // Adds the "release" signing configuration to the release build type. signingConfig signingConfigs.release ... } } } ...
Private Signaturinformationen aus dem Projekt entfernen
Standardmäßig werden Signaturkonfigurationen im Klartext in der build.gradle
-Datei des Moduls gespeichert. Wenn Sie mit einem Team oder an einem Open-Source-Projekt arbeiten, können Sie diese vertraulichen Informationen aus den Build-Dateien verschieben. Gehen Sie dazu so vor:
- Erstellen Sie im Stammverzeichnis Ihres Projekts eine Datei mit dem Namen
keystore.properties
und fügen Sie die folgenden Informationen hinzu:storePassword=myStorePassword keyPassword=myKeyPassword keyAlias=myKeyAlias storeFile=myStoreFileLocation
- Laden Sie in der Datei
build.gradle
die Dateikeystore.properties
wie unten beschrieben. Dies muss vor dem Android-Block erfolgen:Groovy
// Creates a variable called keystorePropertiesFile, and initializes it to the // keystore.properties file. def keystorePropertiesFile = rootProject.file("keystore.properties") // Initializes a new Properties() object called keystoreProperties. def keystoreProperties = new Properties() // Loads the keystore.properties file into the keystoreProperties object. keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android { ... } ...
Kotlin
// Creates a variable called keystorePropertiesFile, and initializes it to the // keystore.properties file. def keystorePropertiesFile = rootProject.file("keystore.properties") // Initializes a new Properties() object called keystoreProperties. def keystoreProperties = new Properties() // Loads the keystore.properties file into the keystoreProperties object. keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) android { ... } ...
- Geben Sie die im
keystoreProperties
-Objekt gespeicherten Informationen zur Signatur ein:Groovy
android { signingConfigs { config { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } ... } ...
Kotlin
android { signingConfigs { config { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } ... } ...
- Klicken Sie in der Benachrichtigungsleiste auf Jetzt synchronisieren.
Weitere Informationen zur App-Signatur finden Sie unter App signieren.
App-Entwicklung vereinfachen
Die folgenden Tipps erleichtern die Entwicklung Ihrer Android-App.
Benutzerdefinierte Felder und Ressourcenwerte für den Code Ihrer App freigeben
Zum Zeitpunkt des Builds generiert Gradle die BuildConfig
-Klasse, damit Ihr App-Code Informationen zum aktuellen Build prüfen kann. Sie können der Klasse BuildConfig
auch über die Methode buildConfigField()
benutzerdefinierte Felder aus Ihrer Gradle-Build-Konfigurationsdatei hinzufügen und im Laufzeitcode Ihrer App auf diese Werte zugreifen. Ebenso können Sie App-Ressourcenwerte mit resValue()
hinzufügen.
Groovy
android { ... buildTypes { release { // These values are defined only for the release build, which // is typically used for full builds and continuous builds. buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"") resValue("string", "build_time", "${minutesSinceEpoch}") ... } debug { // Use static values for incremental builds to ensure that // resource files and BuildConfig aren't rebuilt with each run. // If these rebuild dynamically, they can interfere with // Apply Changes as well as Gradle UP-TO-DATE checks. buildConfigField("String", "BUILD_TIME", "\"0\"") resValue("string", "build_time", "0") } } } ...
Kotlin
android { ... buildTypes { release { // These values are defined only for the release build, which // is typically used for full builds and continuous builds. buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"") resValue("string", "build_time", "${minutesSinceEpoch}") ... } debug { // Use static values for incremental builds to ensure that // resource files and BuildConfig aren't rebuilt with each run. // If these rebuild dynamically, they can interfere with // Apply Changes as well as Gradle UP-TO-DATE checks. buildConfigField("String", "BUILD_TIME", "\"0\"") resValue("string", "build_time", "0") } } } ...
Im App-Code können Sie so auf die Properties zugreifen:
Kotlin
... Log.i(TAG, BuildConfig.BUILD_TIME) Log.i(TAG, getString(R.string.build_time))
Java
... Log.i(TAG, BuildConfig.BUILD_TIME); Log.i(TAG, getString(R.string.build_time));
Properties für das Manifest freigeben
In einigen Fällen musst du dieselbe Property sowohl in deinem Manifest als auch in deinem Code deklarieren (z. B. beim Deklarieren von Behörden für ein FileProvider
). Anstatt dieselbe Property an mehreren Stellen zu aktualisieren, um eine Änderung widerzuspiegeln, definiere eine einzelne Property in der build.gradle
-Datei deines Moduls, um sie sowohl für das Manifest als auch für deinen Code verfügbar zu machen. Beispiel: Weitere Informationen finden Sie unter Build-Variablen in das Manifest einfügen.
Groovy
android { // For settings specific to a product flavor, configure these properties // for each flavor in the productFlavors block. defaultConfig { // Creates a property for the FileProvider authority. def filesAuthorityValue = applicationId + ".files" // Creates a placeholder property to use in the manifest. manifestPlaceholders = [filesAuthority: filesAuthorityValue] // Adds a new field for the authority to the BuildConfig class. buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"") } ... } ...
Kotlin
android { // For settings specific to a product flavor, configure these properties // for each flavor in the productFlavors block. defaultConfig { // Creates a property for the FileProvider authority. val filesAuthorityValue = applicationId + ".files" // Creates a placeholder property to use in the manifest. manifestPlaceholders["filesAuthority"] = filesAuthorityValue // Adds a new field for the authority to the BuildConfig class. buildConfigField("String", "FILES_AUTHORITY", "\"${filesAuthorityValue}\"") } ... } ...
Rufen Sie den Platzhalter in Ihrem Manifest so auf:
<manifest> ... <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="${filesAuthority}" android:exported="false" android:grantUriPermissions="true"> ... </provider> </application> </manifest>
Der Zugriff auf das Feld FILES_AUTHORITY
im Code Ihrer App sieht in etwa so aus:
Kotlin
... val contentUri: Uri = FileProvider.getUriForFile(context, BuildConfig.FILES_AUTHORITY, myFile)
Java
... Uri contentUri = FileProvider.getUriForFile(getContext(), BuildConfig.FILES_AUTHORITY, myFile);