Làm cách nào để đọc các thuộc tính được xác định trong local.properties trong build.gradle


88

Tôi đã thiết lập sdk.dirndk.dirtrong local.properties.

Làm cách nào để đọc các giá trị được xác định trong sdk.dirndk.dirtrong build.gradletệp?


15
câu hỏi thực sự là: tại sao cái này không được tích hợp sẵn trong plugin android gradle?!?!?!?!
Armand

@Armand: có thể vì local.propertiesnó đang được sử dụng cho cấu hình cục bộ của Android Studio và việc có một tệp khác cùng tên có thể tạo ra một chút nhầm lẫn. Xem stackoverflow.com/a/49306091/1587329 bên dưới
serv-inc

1
@Armand thật tiếc là cái này không được xây dựng vào 5 năm trước, nhưng sau này nó đã được thêm vào: android.getSdkDirectory()đơn giản là hoạt động.
Alex Cohn

Câu trả lời:


138

Bạn có thể làm điều đó theo cách này:

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

Sử dụng project.rootProjectnếu bạn đang đọc tệp thuộc tính trong một dự án con 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

Trong trường hợp tệp thuộc tính nằm trong cùng một thư mục dự án con, bạn chỉ có thể sử dụng project.


3
"Project.rootProject" là gì?
AlexBalo,

1
Thêm một lời giải thích ngắn gọn
rciovati

Ý bạn là gì với dự án? Lý tưởng của tôi là cho tôi một lỗi. Làm cách nào để tôi có được đường dẫn dự án.
AlexBalo,

Bên trong build.gradletệp projectlà một biến thể đề cập đến dự án hiện tại. Nếu bạn có lỗi lạ, hãy hỏi một câu hỏi mới.
rciovati

Nếu tôi sao chép mã của bạn bên trong một lớp tiện ích trong app / src / main / java / my_package_name / Utils.java thì không thể giải quyết được. Làm cách nào để đọc local.properties từ một lớp Tiện ích?
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", "")
}

và trong mã, bạn lấy nó dưới dạng chuỗi khác từ Tài nguyên -

resources.getString(R.string.default_account_iccid);

2
Đây là câu trả lời chính xác. Làm thế nào nó không được chọn? Câu trả lời đã chọn thậm chí không cung cấp giải pháp ??
Joshua Pinter

10

Mặc dù câu trả lời của @ rciovati chắc chắn là đúng, nhưng cũng có một cách khác để đọc các giá trị cho sdk.dirndk.dir .

Như đã chỉ ra trong mục blog này của Gaku Ueda (Thư mục lấy ndk), BasePluginlớp này cung cấp các phương thức cho getNdkFolder()getSdkFolder():

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

Lưu ý: Bạn có thể phải thay đổi com.android.applicationthànhcom.android.library nếu bạn đang xây dựng một thư viện

Đây có thể là một cách tốt hơn để đọc các giá trị thư mục. Mặc dù phải nói rằng câu trả lời do @rciovati cung cấp linh hoạt hơn, vì người ta có thể đọc bất kỳ giá trị nào trong tệp thuộc tính.


1
Đối với Gradle 1.1.0, bạn cần sử dụng plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()như có thể thấy ở đây: stackoverflow.com/questions/28615439/…
Stephan

1
Bị hỏng một lần nữa khi chuyển sang plugin "thử nghiệm" :(
Alex Cohn

8

Câu trả lời tải local.properties theo cách thủ công ở trên rõ ràng là hoạt động và câu trả lời tiếp theo yêu cầu bạn biết plugin nào được áp dụng cũng sẽ hoạt động.

Những cách tiếp cận này có thể tốt hơn một chút đối với một số người vì chúng chung chung hơn vì chúng hoạt động bất kể bạn đang sử dụng plugin Ứng dụng, Thử nghiệm hay Thư viện. Các đoạn mã này cũng cung cấp cho bạn quyền truy cập có lập trình đầy đủ vào tất cả cấu hình plugin Android (Hương vị sản phẩm, phiên bản Công cụ xây dựng, v.v.):

Nếu bạn cần quyền truy cập vào tệp build.gradle đang sử dụng Plugin Android Gradle, chỉ cần truy cập trực tiếp vào Android DSL vì nó hiện có sẵn trực tiếp:

project.android.sdkDirectory

Dạng dài hơn (bên dưới) của điều này rất hữu ích nếu bạn đang tạo các lớp hoặc Plugin Gradle Tasks tùy chỉnh hoặc chỉ đơn giản là muốn xem các thuộc tính nào có sẵn.

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

Tại thời điểm đăng bài này cũng có một adbExe tài sản mà chắc chắn đáng chú ý.

Mã này phải thực thi SAU KHI Trình cắm Android Gradle được định cấu hình theo vòng quay Gradle. Thông thường, điều này có nghĩa là bạn đặt nó vàoexecute phương thức a Taskhoặc đặt nó SAU KHI androidkhai báo DSL trong build.gradletệp ứng dụng / thư viện Android ).

Các đoạn mã này cũng đi kèm với cảnh báo rằng khi bạn nâng cấp phiên bản Plugin Android Gradle, các thuộc tính này có thể thay đổi khi plugin được phát triển, vì vậy bạn chỉ cần kiểm tra khi di chuyển giữa các phiên bản của plugin Gradle và Android Gradle cũng như Android Studio (đôi khi là phiên bản mới của Android Studio yêu cầu phiên bản mới của Trình cắm Android Gradle).


3

Tôi nghĩ đó là cách thanh lịch hơn.

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

nó hoạt động trên android gradle 1.5.0.


1

Tôi đã thiết lập sdk.dirndk.dirtrong local.properties.

Bạn có thể xem xét lại nếu bạn muốn giá trị bằng tay bộ trong local.propertieskhi đó đã được sử dụng bởi Android Studio (đối với dự án root), và

bạn không nên sửa đổi tệp này theo cách thủ công hoặc kiểm tra nó trong hệ thống kiểm soát phiên bản của bạn.

nhưng hãy xem miễn trừ cụ thể về cmake được liệt kê trong các nhận xét.


Hoàn toàn trái ngược: tệp được Android Studio duy trì và đôi khi thật tuyệt khi đọc nội dung của nó. May mắn thay, điều này hiện đã được hỗ trợ:android.getSdkDirectory()
Alex Cohn

@AlexCohn: chắc chắn, đọc có vẻ tốt. Câu trả lời chỉ đề cập đến việc thiết lập các giá trị theo cách thủ công. Hy vọng rõ ràng hơn bây giờ.
serv-inc

Thao tác thủ công của local.propertiescũng là hợp pháp. Xem developer.android.com/studio/projects/… : Google khuyên bạn nên thêm cmake.dir="path-to-cmake"để ghi đè hành vi tra cứu mặc định.
Alex Cohn

@AlexCohn: như một sự lựa chọn. Với những lời báo trước If you set this property, Gradle no longer uses PATH to find CMake.. Vì vậy, những gì bạn đảm nhận nó? Bạn có khuyên bạn nên sử dụng nó không hay bạn chỉ đề cập rằng nó có thể được thay đổi trong một số trường hợp? Đó là: điều này KHÔNG NÊN giống như trong RFC2119 : cố gắng làm theo cách đó trừ khi có lý do chính đáng?
serv-inc vào

1
Tôi diễn giải cụm từ này theo cách khác. "Gradle không còn sử dụng PATH để tìm CMake" là mục đích đã được ghi nhận cmake.dirđể thêm vào local.properties chứ không phải là một số cảnh báo hoặc tác dụng phụ của việc làm điều gì đó nguy hiểm. Không phải tôi, mà là Google khuyên bạn nên sử dụng nó, khi có lý do chính đáng (tức là nếu bạn không muốn Gradle sử dụng PATH để tìm CMake).
Alex Cohn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.