Jak czytać właściwości zdefiniowane w local.properties w build.gradle

89

Mam ustawiony sdk.diri ndk.dirw local.properties.

Jak odczytać wartości zdefiniowane w pliku sdk.diri ndk.dirw build.gradlepliku?

Vikram
źródło
15
Prawdziwe pytanie brzmi: dlaczego nie jest to wbudowane we wtyczkę Android Gradle?!?!?!?!
Armand
@Armand: być może dlatego, że local.propertiesjest używany dla własnej lokalnej konfiguracji Android Studio, a posiadanie innego pliku o tej samej nazwie może spowodować trochę zamieszania. Zobacz stackoverflow.com/a/49306091/1587329 poniżej
serv-inc
1
@Armand szkoda, że ​​nie został zbudowany 5 lat temu, ale później dodano: android.getSdkDirectory()po prostu działa.
Alex Cohn

Odpowiedzi:

139

Możesz to zrobić w ten sposób:

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

Użyj, project.rootProjectjeśli czytasz plik właściwości w podprojekcie 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

W przypadku, gdy plik właściwości znajduje się w tym samym katalogu podprojektu, którego możesz użyć po prostu project.

rciovati
źródło
3
Co to jest „project.rootProject”?
AlexBalo,
1
Dodano krótkie wyjaśnienie
rciovati
Co masz na myśli mówiąc o projekcie? Mój ide daje mi błąd. Jak uzyskać ścieżkę projektu.
AlexBalo,
Wewnątrz build.gradlepliku projectznajduje się zmienna, która odnosi się do bieżącego projektu. Jeśli masz dziwne błędy, zadaj nowe pytanie.
rciovati
Jeśli skopiuję twój kod do klasy narzędzi w app / src / main / java / my_package_name / Utils.java, nie można tego rozwiązać. Jak mogę czytać local.properties z klasy 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", "")
}

aw kodzie otrzymujesz go jako inny ciąg z zasobów -

resources.getString(R.string.default_account_iccid);
Dmitrijs
źródło
2
To jest poprawna odpowiedź. Dlaczego nie jest wybierany? Wybrana odpowiedź nawet nie dostarcza rozwiązania?
Joshua Pinter
10

Chociaż odpowiedź @ rciovati jest z pewnością poprawna, istnieje również alternatywny sposób odczytywania wartości sdk.diri ndk.dir.

Jak wskazano w tym wpisie na blogu Gaku Ueda (Getting ndk directory), BasePluginklasa oferuje metody dla getNdkFolder()i getSdkFolder():

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

Uwaga: może być konieczna zmiana com.android.applicationna, com.android.libraryjeśli tworzysz bibliotekę

To może być bardziej elegancki sposób odczytywania wartości folderów. Chociaż trzeba powiedzieć, że odpowiedź udzielona przez @rciovati jest bardziej elastyczna, ponieważ można było odczytać dowolną wartość w pliku właściwości.

super-qua
źródło
1
W przypadku Gradle 1.1.0 musisz użyć, plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()jak widać tutaj: stackoverflow.com/questions/28615439/ ...
Stephan
1
Znów zepsuty po przejściu na wtyczkę „eksperymentalną” :(
Alex Cohn,
8

Odpowiedź, która wczytuje ręcznie plik local.properties powyżej, oczywiście działa, a następna, która wymaga, abyś wiedział, która wtyczka została zastosowana, powinna również działać.

Te podejścia mogą być trochę lepsze dla niektórych, ponieważ są bardziej ogólne, ponieważ działają niezależnie od tego, czy używasz wtyczki Aplikacja, Test czy Biblioteka. Te fragmenty zapewniają również pełny programistyczny dostęp do całej konfiguracji wtyczki Androida (smaki produktu, wersja narzędzi do budowania i wiele więcej):

Jeśli potrzebujesz dostępu w pliku build.gradle, który używa wtyczki Android Gradle, po prostu uzyskaj bezpośredni dostęp do Android DSL, ponieważ jest teraz dostępny bezpośrednio:

project.android.sdkDirectory

Dłuższa forma (poniżej) jest przydatna, jeśli tworzysz niestandardowe klasy Gradle Tasks lub wtyczki lub po prostu chcesz zobaczyć, które właściwości są dostępne.

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

W momencie tego wpisu istnieje również przydatna adbExewłaściwość, na którą zdecydowanie warto zwrócić uwagę.

Ten kod musi zostać wykonany PO skonfigurowaniu wtyczki Android Gradle zgodnie z cyklem życia Gradle. Zwykle oznacza to, że umieszczasz go w executemetodzie a Tasklub umieszczasz PO androiddeklaracji DSL w pliku aplikacji / bibliotek systemu Android build.gradle).

Te fragmenty zawierają również zastrzeżenie, że podczas uaktualniania wersji wtyczki Android Gradle właściwości te mogą ulec zmianie wraz z tworzeniem wtyczki, więc po prostu przetestuj podczas przechodzenia między wersjami wtyczki Gradle i Android Gradle, a także Android Studio (czasami nowa wersja Androida Studio wymaga nowej wersji wtyczki Android Gradle).

PaulR
źródło
3

Myślę, że to bardziej elegancki sposób.

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

działa na Androidzie Gradle 1.5.0.

Victor Choy
źródło
1

Mam ustawiony sdk.diri ndk.dirw local.properties.

Możesz ponownie rozważyć, czy chcesz ręcznie ustawić wartości w, local.propertiesponieważ jest już używane przez Android Studio (dla projektu głównego) i

nie należy modyfikować tego pliku ręcznie ani wpisywać go do systemu kontroli wersji.

ale zobacz szczególne wyjątki dotyczące cmake wymienione w komentarzach.

serv-inc
źródło
Wręcz przeciwnie: plik jest obsługiwany przez Android Studio i czasami miło jest przeczytać jego zawartość. Na szczęście jest to teraz obsługiwane:android.getSdkDirectory()
Alex Cohn
@AlexCohn: jasne, czytanie brzmi dobrze. Odpowiedź dotyczy tylko ręcznego ustawiania wartości. Mam nadzieję, że teraz jaśniej.
serv-inc
Ręczna manipulacja local.propertiesjest również uzasadniona. Zobacz developer.android.com/studio/projects/… : Google zaleca dodanie w cmake.dir="path-to-cmake"celu zastąpienia domyślnego sposobu wyszukiwania.
Alex Cohn
@AlexCohn: jako jeden wybór. Z zastrzeżeniem If you set this property, Gradle no longer uses PATH to find CMake.. Więc co o tym sądzisz? Czy polecasz go używać, czy po prostu wspominasz, że w niektórych przypadkach można go zmienić? To znaczy: to NIE POWINNO być tak, jak w RFC2119 : próbować to zrobić w ten sposób, chyba że istnieją dobre powody?
serv-inc
1
Inaczej interpretuję to zdanie. „Gradle nie używa już PATH do znajdowania CMake” jest udokumentowanym celem dodania cmake.dirdo local.properties , a nie jakiegoś zastrzeżenia lub efektu ubocznego zrobienia czegoś niebezpiecznego. To nie ja, to Google polecam go używać, gdy jest dobry powód (tj. Jeśli nie chcesz, aby Gradle używał PATH do znajdowania CMake).
Alex Cohn