Wie lese ich Eigenschaften, die in local.properties in build.gradle definiert sind?

88

Ich habe gesetzt sdk.dirund ndk.dirin local.properties.

Wie lese ich die in sdk.dirund ndk.dirin der build.gradleDatei definierten Werte ?

Vikram
quelle
15
Die eigentliche Frage ist: Warum ist das nicht in das Android Gradle Plugin integriert?!?!?!?!
Armand
@Armand: Vielleicht, weil local.propertieses für die lokale Konfiguration von Android Studio verwendet wird und eine andere Datei mit demselben Namen ein wenig Verwirrung stiftet . Siehe stackoverflow.com/a/49306091/1587329 unten
serv-inc
1
@Armand Es ist schade, dass dies nicht vor 5 Jahren gebaut wurde, aber später wurde dies hinzugefügt: android.getSdkDirectory()funktioniert einfach.
Alex Cohn

Antworten:

134

Sie können dies folgendermaßen tun:

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

Verwenden project.rootProjectSie diese Option, wenn Sie die Eigenschaftendatei in einem Unterprojekt lesen 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

Wenn sich die Eigenschaftendatei im selben Unterprojektverzeichnis befindet, können Sie nur verwenden project.

rciovati
quelle
3
Was ist "project.rootProject"?
AlexBalo
1
Eine kurze Erklärung
hinzugefügt
Was meinst du mit Projekt? Meine Idee gibt mir einen Fehler. Wie bekomme ich den Projektpfad?
AlexBalo
In einer build.gradleDatei projectbefindet sich eine Variable, die sich auf das aktuelle Projekt bezieht. Wenn Sie seltsame Fehler haben, stellen Sie eine neue Frage.
Rciovati
Wenn ich Ihren Code in eine Dienstprogrammklasse in app / src / main / java / my_package_name / Utils.java kopiere, kann er nicht aufgelöst werden. Wie kann ich local.properties aus einer Utility-Klasse lesen?
AlexBalo
24

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", "")
}

und im Code erhalten Sie es als andere Zeichenfolge von Resources -

resources.getString(R.string.default_account_iccid);
Dmitrijs
quelle
2
Dies ist die richtige Antwort. Wie wird es nicht ausgewählt? Die gewählte Antwort bietet nicht einmal eine Lösung?
Joshua Pinter
10

Obwohl die Antwort von @ rciovati sicherlich richtig ist, gibt es auch eine alternative Möglichkeit, die Werte für sdk.dirund zu lesen ndk.dir.

Wie in diesem Blogeintrag von Gaku Ueda (Getting ndk directory) ausgeführt BasePlugin, bietet die Klasse Methoden für getNdkFolder()und getSdkFolder():

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

Hinweis: Möglicherweise müssen Sie zu ändern com.android.application, com.android.librarywenn Sie eine Bibliothek erstellen

Dies ist möglicherweise eine elegantere Methode zum Lesen der Ordnerwerte. Obwohl gesagt werden muss, dass die Antwort von @rciovati flexibler ist, da man jeden Wert in der Eigenschaftendatei lesen kann.

Super-Qua
quelle
1
Für Gradle 1.1.0 müssen Sie verwenden, plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()wie hier zu sehen ist: stackoverflow.com/questions/28615439/…
Stephan
1
Wieder gebrochen mit der Umstellung auf "experimentelles" Plugin :(
Alex Cohn
8

Die Antwort, die local.properties oben manuell lädt, funktioniert offensichtlich, und die nächste, bei der Sie wissen müssen, welches Plugin angewendet wurde, sollte ebenfalls funktionieren.

Diese Ansätze sind für einige möglicherweise etwas besser, da sie allgemeiner sind, da sie unabhängig davon funktionieren, ob Sie das Anwendungs-, Test- oder Bibliotheks-Plugin verwenden. Mit diesen Snippets erhalten Sie außerdem vollen programmgesteuerten Zugriff auf alle Android-Plugin-Konfigurationen (Product Flavours, Build Tools-Version und vieles mehr):

Wenn Sie Zugriff auf eine build.gradle-Datei benötigen, die das Android Gradle Plugin verwendet, greifen Sie einfach direkt auf Android DSL zu, da es jetzt direkt verfügbar ist:

project.android.sdkDirectory

Die längere Form (unten) ist praktisch, wenn Sie benutzerdefinierte Gradle Tasks-Klassen oder Plugins erstellen oder einfach nur anzeigen möchten, welche Eigenschaften verfügbar sind.

// 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}");

Zum Zeitpunkt dieser Veröffentlichung gibt es auch eine praktische adbExeEigenschaft, die definitiv erwähnenswert ist.

Dieser Code muss ausgeführt werden, nachdem das Android Gradle Plugin für den Gradle Livecycle konfiguriert wurde. In der Regel bedeutet dies, dass Sie es in die executeMethode von a Taskeinfügen oder NACH der androidDSL-Deklaration in eine Android-App / Bibliotheksdatei build.gradleeinfügen.

Diese Snippets enthalten auch die Einschränkung, dass sich diese Eigenschaften beim Aktualisieren der Android Gradle Plugin-Versionen ändern können, wenn das Plugin entwickelt wird. Testen Sie also einfach, wenn Sie zwischen Versionen des Gradle- und Android Gradle-Plugins sowie Android Studio (manchmal eine neue Version von Android) wechseln Studio benötigt eine neue Version des Android Gradle Plugins.

PaulR
quelle
3

Ich denke, es ist eleganter.

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

es funktioniert auf Android Gradle 1.5.0.

Victor Choy
quelle
1

Ich habe gesetzt sdk.dirund ndk.dirin local.properties.

Sie können es sich noch einmal überlegen, ob Sie Werte manuell festlegen möchten, local.propertiesda diese bereits von Android Studio (für das Root-Projekt) verwendet werden

Sie sollten diese Datei nicht manuell ändern oder in Ihr Versionskontrollsystem einchecken.

Beachten Sie jedoch die in den Kommentaren aufgeführte spezifische Ausnahme für cmake.

serv-inc
quelle
Ganz im Gegenteil: Die Datei wird von Android Studio verwaltet und manchmal ist es schön, ihren Inhalt zu lesen. Zum Glück wird dies jetzt unterstützt:android.getSdkDirectory()
Alex Cohn
@ AlexCohn: Klar, Lesen hört sich gut an. Die Antwort befasst sich nur mit der manuellen Einstellung der Werte. Hoffentlich jetzt klarer.
serv-inc
Manuelle Manipulation von local.propertiesist ebenfalls legitim. Siehe developer.android.com/studio/projects/… : Google empfiehlt das Hinzufügen cmake.dir="path-to-cmake", um das Standard-Suchverhalten zu überschreiben.
Alex Cohn
@ AlexCohn: als eine Wahl. Mit der Einschränkung If you set this property, Gradle no longer uses PATH to find CMake.. Wie sehen Sie das? Empfehlen Sie die Verwendung oder erwähnen Sie einfach, dass es in einigen Fällen geändert werden kann? Das heißt: Dies sollte NICHT wie in RFC2119 sein : Versuchen Sie es so, es sei denn, es gibt gute Gründe?
serv-inc
1
Ich interpretiere diesen Satz anders. "Gradle verwendet PATH nicht mehr, um CMake zu finden" ist der dokumentierte Zweck des Hinzufügens cmake.dirzu local.properties , nicht irgendein Vorbehalt oder Nebeneffekt, etwas Gefährliches zu tun. Ich bin es nicht, sondern Google, der die Verwendung empfiehlt, wenn es einen guten Grund gibt (dh wenn Sie nicht möchten, dass Gradle PATH verwendet, um CMake zu finden).
Alex Cohn