Bagaimana cara membaca properti yang ditentukan di local.properties di build.gradle

89

Saya telah mengatur sdk.dirdan ndk.dirmasuk local.properties.

Bagaimana cara membaca nilai yang ditentukan di dalam sdk.dirdan ndk.dirdi dalam build.gradlefile?

Vikram
sumber
15
pertanyaan sebenarnya adalah: mengapa ini tidak ada di dalam plugin gradle android?!?!?!?!
Armand
@Armand: mungkin karena local.propertiessedang digunakan untuk konfigurasi lokal Android Studio sendiri, dan memiliki file lain dengan nama yang sama dapat menimbulkan sedikit kebingungan. Lihat stackoverflow.com/a/49306091/1587329 di bawah ini
serv-inc
1
@Armand sayang sekali ini tidak dibangun pada 5 tahun yang lalu, tetapi kemudian ini ditambahkan: android.getSdkDirectory()hanya berfungsi.
Alex Cohn

Jawaban:

139

Anda dapat melakukannya dengan cara ini:

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

Gunakan project.rootProjectjika Anda membaca file properti dalam sub-proyek 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

Jika file properti berada dalam direktori sub-proyek yang sama, Anda hanya dapat menggunakan project.

rciovati.dll
sumber
3
Apa itu "project.rootProject"?
AlexBalo
1
Menambahkan penjelasan singkat
rciovati
Apa yang Anda maksud dengan proyek? Ide saya memberi saya kesalahan. Bagaimana cara mendapatkan jalur proyek.
AlexBalo
Di dalam build.gradlefile projectadalah variabile yang mengacu pada proyek saat ini. Jika Anda memiliki kesalahan aneh, ajukan pertanyaan baru.
rciovati
Jika saya menyalin kode Anda di dalam kelas utilitas di app / src / main / java / my_package_name / Utils.java itu tidak dapat diselesaikan. Bagaimana cara membaca properti local.properties dari kelas 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", "")
}

dan dalam kode Anda mendapatkannya sebagai string lain dari Resources -

resources.getString(R.string.default_account_iccid);
Dmitrijs
sumber
2
Ini jawaban yang benar. Bagaimana tidak dipilih? Jawaban yang dipilih bahkan tidak memberikan solusi ??
Joshua Pinter
10

Meskipun jawaban @ rciovati sudah pasti benar, ada juga cara alternatif untuk membaca nilai untuk sdk.dirdan ndk.dir.

Seperti yang ditunjukkan dalam entri blog ini oleh Gaku Ueda (Mendapatkan direktori ndk) BasePluginkelas menawarkan metode untuk getNdkFolder()dan getSdkFolder():

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

Catatan: Anda mungkin harus mengubah com.android.applicationke com.android.libraryjika Anda sedang membangun perpustakaan

Ini mungkin cara yang lebih elegan untuk membaca nilai folder. Meskipun harus dikatakan bahwa jawaban yang diberikan oleh @rciovati lebih fleksibel, karena seseorang dapat membaca nilai apa pun di file properti.

super-qua
sumber
1
Untuk Gradle 1.1.0 Anda perlu menggunakan plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()seperti yang dapat dilihat di sini: stackoverflow.com/questions/28615439/…
Stephan
1
Rusak lagi dengan peralihan ke plugin "eksperimental" :(
Alex Cohn
8

Jawaban yang memuat properti local.properties secara manual di atas jelas berfungsi, dan jawaban berikutnya yang mengharuskan Anda mengetahui plugin mana yang diterapkan harus berfungsi juga.

Pendekatan ini mungkin sedikit lebih baik untuk beberapa orang karena lebih umum karena berfungsi terlepas dari apakah Anda menggunakan plugin Application, Test, atau Library. Cuplikan ini juga memberi Anda akses terprogram penuh ke semua konfigurasi plugin Android (Ragam Produk, versi Build Tools, dan banyak lagi):

Jika Anda memerlukan akses dalam file build.gradle yang menggunakan Android Gradle Plugin, cukup akses Android DSL secara langsung karena sekarang tersedia secara langsung:

project.android.sdkDirectory

Bentuk yang lebih panjang (di bawah) berguna jika Anda membuat kelas atau Plugin Gradle Tasks kustom atau hanya ingin melihat properti mana yang tersedia.

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

Pada saat posting ini ada juga adbExeproperti praktis yang pasti perlu diperhatikan.

Kode ini harus dijalankan SETELAH Android Gradle Plugin dikonfigurasi per siklus hidup Gradle. Biasanya ini berarti Anda memasukkannya ke dalam executemetode Taskatau meletakkannya SETELAH androiddeklarasi DSL di build.gradlefile aplikasi / perpustakaan Android ).

Cuplikan ini juga disertai peringatan bahwa saat Anda mengupgrade versi Android Gradle Plugin, properti ini dapat berubah saat plugin dikembangkan, jadi cukup uji saat berpindah antara versi Gradle dan plugin Android Gradle serta Android Studio (terkadang versi baru Android Studio membutuhkan versi baru Android Gradle Plugin).

PaulR
sumber
3

Saya pikir itu cara yang lebih elegan.

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

ini bekerja pada android gradle 1.5.0.

Victor Choy
sumber
1

Saya telah mengatur sdk.dirdan ndk.dirmasuk local.properties.

Anda dapat mempertimbangkan kembali jika Anda ingin menyetel nilai secara manual local.propertiesseperti yang sudah digunakan oleh Android Studio (untuk proyek root), dan

Anda tidak boleh memodifikasi file ini secara manual atau memeriksanya ke dalam sistem kontrol versi Anda.

tetapi lihat pengecualian khusus tentang cmake yang tercantum di komentar.

serv-inc
sumber
Justru sebaliknya: file tersebut dikelola oleh Android Studio, dan terkadang isinya menyenangkan untuk dibaca. Untungnya, ini sekarang didukung:android.getSdkDirectory()
Alex Cohn
@AlexCohn: tentu saja, membaca terdengar bagus. Jawabannya hanya berhubungan dengan pengaturan nilai secara manual. Semoga lebih jelas sekarang.
serv-inc
Manipulasi manual local.propertiesjuga sah. Lihat developer.android.com/studio/projects/… : Google menyarankan untuk menambahkan cmake.dir="path-to-cmake"guna menimpa perilaku pencarian default.
Alex Cohn
@AlexCohn: sebagai salah satu pilihan. Dengan peringatan itu If you set this property, Gradle no longer uses PATH to find CMake.. Jadi apa pendapat Anda tentang itu? Apakah Anda merekomendasikan untuk menggunakannya, atau apakah Anda hanya menyebutkan bahwa itu dapat diubah dalam beberapa kasus? Yaitu: ini HARUS TIDAK seperti di RFC2119 : coba lakukan seperti itu kecuali ada alasan bagus?
serv-inc
1
Saya menafsirkan frasa ini secara berbeda. "Gradle tidak lagi menggunakan PATH untuk menemukan CMake" adalah tujuan didokumentasikan menambahkan cmake.diruntuk local.properties , tidak beberapa peringatan atau efek samping dari melakukan sesuatu yang berbahaya. Bukan saya, melainkan Google yang merekomendasikan untuk menggunakannya, jika ada alasan bagus (misalnya, jika Anda tidak ingin Gradle menggunakan PATH untuk menemukan CMake).
Alex Cohn