Comment lire les propriétés définies dans local.properties dans build.gradle

89

J'ai mis sdk.diret ndk.dirdedans local.properties.

Comment lire les valeurs définies dans sdk.diret ndk.dirdans le build.gradlefichier?

Vikram
la source
15
la vraie question est: pourquoi n'est-ce pas intégré au plugin android gradle?!?!?!?!
Armand
@Armand: peut-être parce qu'il local.propertiesest utilisé pour la configuration locale d'Android Studio, et avoir un autre fichier du même nom pourrait créer un peu de confusion. Voir stackoverflow.com/a/49306091/1587329 ci
serv-inc
1
@Armand c'est dommage que cela n'ait pas été construit il y a 5 ans, mais plus tard, cela a été ajouté: android.getSdkDirectory()fonctionne simplement.
Alex Cohn

Réponses:

139

Vous pouvez le faire de cette manière:

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def sdkDir = properties.getProperty('sdk.dir')
def ndkDir = properties.getProperty('ndk.dir')

À utiliser project.rootProjectsi vous lisez le fichier de propriétés dans un sous-projet build.gradle:

.
├── app
│   ├── build.gradle <-- You are reading the local.properties in this gradle build file
│   └── src
├── build.gradle
├── gradle
├── gradlew
├── gradlew.bat
├── settings.gradle
└── local.properties

Si le fichier de propriétés se trouve dans le même répertoire de sous-projet, vous pouvez simplement l'utiliser project.

rciovati
la source
3
Qu'est-ce que "project.rootProject"?
AlexBalo
1
Ajout d'une brève explication
rciovati
Que voulez-vous dire par projet? Mon idée me donne une erreur. Comment obtenir le chemin du projet.
AlexBalo
À l'intérieur d'un build.gradlefichier se projecttrouve une variable qui fait référence au projet en cours. Si vous avez des erreurs étranges, posez une nouvelle question.
rciovati
Si je copie votre code dans une classe utilitaire dans app / src / main / java / mon_nom_package / Utils.java, il ne peut pas être résolu. Comment puis-je lire local.properties à partir d'une classe Utility?
AlexBalo
26

local.properties

default.account.iccid=123

build.gradle -

def Properties properties = new Properties()
properties.load(project.rootProject.file("local.properties").newDataInputStream())

defaultConfig {

    resValue "string", "default_account_iccid", properties.getProperty("default.account.iccid", "")
}

et dans le code, vous l'obtenez comme une autre chaîne de Resources -

resources.getString(R.string.default_account_iccid);
Dmitrijs
la source
2
C'est la bonne réponse. Comment n'est-il pas sélectionné? La réponse choisie n'apporte même pas de solution ??
Joshua Pinter
10

Bien que la réponse de @ rciovati soit certainement correcte, il existe également une autre façon de lire les valeurs pour sdk.diret ndk.dir.

Comme indiqué dans cette entrée de blog par Gaku Ueda (Obtenir le répertoire ndk), la BasePluginclasse propose des méthodes pour getNdkFolder()et getSdkFolder():

def ndkDir = project.plugins.findPlugin('com.android.application').getNdkFolder()
def sdkDir = project.plugins.findPlugin('com.android.application').getSdkFolder()

Remarque: vous devrez peut-être changer com.android.applicationpour com.android.librarysi vous créez une bibliothèque

C'est peut-être une manière plus élégante de lire les valeurs des dossiers. Bien qu'il faille dire que la réponse fournie par @rciovati est plus flexible, car on peut lire n'importe quelle valeur dans le fichier de propriétés.

super-qua
la source
1
Pour Gradle 1.1.0, vous devez utiliser plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()comme on peut le voir ici: stackoverflow.com/questions/28615439/…
Stephan
1
Cassé à nouveau avec le passage au plugin "expérimental" :(
Alex Cohn
8

La réponse qui charge local.properties manuellement ci-dessus fonctionne évidemment, et la suivante qui vous demande de savoir quel plugin a été appliqué devrait également fonctionner.

Ces approches peuvent être un peu meilleures pour certains car elles sont plus génériques car elles fonctionnent que vous utilisiez le plugin Application, Test ou Library. Ces extraits vous donnent également un accès programmatique complet à toute la configuration du plugin Android (Product Flavors, Build Tools version, et bien plus encore):

Si vous avez besoin d'accéder à un fichier build.gradle qui utilise le plug-in Android Gradle, accédez simplement au DSL Android directement car il est maintenant disponible directement:

project.android.sdkDirectory

La forme la plus longue (ci-dessous) est pratique si vous créez des classes ou des plugins Gradle Tasks personnalisés ou si vous souhaitez simplement afficher les propriétés disponibles.

// def is preferred to prevent having to add a build dependency.
def androidPluginExtension = project.getExtensions().getByName("android");

// List available properties.
androidPluginExtension.properties.each { Object key, Object value ->
    logger.info("Extension prop: ${key} ${value}")
}
String sdkDir = androidPluginExtension.getProperties().get("sdkDirectory");
System.out.println("Using sdk dir: ${sdkDir}");

Au moment de cette publication, il y a aussi une adbExepropriété pratique qui vaut vraiment la peine d'être notée.

Ce code doit s'exécuter APRÈS que le plug-in Android Gradle soit configuré selon le cycle de vie Gradle. Cela signifie généralement que vous le mettez dans la executeméthode a Taskou que vous le placez APRÈS la androiddéclaration DSL dans un build.gradlefichier d' application / bibliothèques Android ).

Ces extraits contiennent également l'avertissement que lorsque vous mettez à niveau les versions du plug-in Android Gradle, ces propriétés peuvent changer au fur et à mesure que le plug-in est développé, alors testez simplement lorsque vous passez d'une version du plug-in Gradle à Android Gradle ainsi qu'à Android Studio (parfois une nouvelle version d'Android. Studio nécessite une nouvelle version du plugin Android Gradle).

PaulR
la source
3

Je pense que c'est de manière plus élégante.

println "${android.getSdkDirectory().getAbsolutePath()}"

cela fonctionne sur android gradle 1.5.0.

Victor Choy
la source
1

J'ai mis sdk.diret ndk.dirdedans local.properties.

Vous pouvez reconsidérer si vous souhaitez définir manuellement des valeurs dans local.propertiescar cela est déjà utilisé par Android Studio (pour le projet racine), et

vous ne devez pas modifier ce fichier manuellement ou l'enregistrer dans votre système de contrôle de version.

mais voir l'exemption spécifique concernant cmake répertoriée dans les commentaires.

serv-inc
la source
Bien au contraire: le fichier est maintenu par Android Studio, et il est parfois agréable de lire son contenu. Heureusement, ceci est maintenant pris en charge:android.getSdkDirectory()
Alex Cohn
@AlexCohn: bien sûr, la lecture sonne bien. La réponse ne concerne que la définition manuelle des valeurs. Espérons plus clair maintenant.
serv-inc
La manipulation manuelle de local.propertiesest également légitime. Voir developer.android.com/studio/projects/… : Google recommande d'ajouter cmake.dir="path-to-cmake"pour remplacer le comportement de recherche par défaut.
Alex Cohn
@AlexCohn: comme un choix. Avec la mise en garde If you set this property, Gradle no longer uses PATH to find CMake.. Alors, quelle est votre opinion là-dessus? Recommandez-vous de l'utiliser ou mentionnez-vous simplement qu'il peut être modifié dans certains cas? C'est-à-dire: cela NE DEVRAIT PAS être comme dans RFC2119 : essayez de le faire de cette façon à moins qu'il n'y ait de bonnes raisons?
serv-inc
1
J'interprète cette phrase différemment. "Gradle n'utilise plus PATH pour trouver CMake" est le but documenté de l'ajout cmake.dirà local.properties , et non une mise en garde ou un effet secondaire de faire quelque chose de dangereux. Ce n'est pas moi, c'est Google qui recommande de l'utiliser, quand il y a une bonne raison (par exemple, si vous ne voulez pas que Gradle utilise PATH pour trouver CMake).
Alex Cohn