【问题标题】:How do I read properties defined in local.properties in build.gradle如何读取 build.gradle 中 local.properties 中定义的属性
【发布时间】:2014-03-26 19:52:16
【问题描述】:

我在local.properties中设置了sdk.dirndk.dir

如何读取build.gradle文件中sdk.dirndk.dir的值?

【问题讨论】:

  • 真正的问题是:为什么这不是内置到 android gradle 插件中的?!?!?!?!
  • @Armand: 可能是因为local.properties 用于 Android Studio 自己的本地配置,并且拥有另一个同名文件可能会造成一点混乱。请参阅下面的stackoverflow.com/a/49306091/1587329
  • @Armand 很遗憾这不是 5 年前建成的,但后来添加了这个:android.getSdkDirectory() 可以正常工作。

标签: android gradle android-gradle-plugin build.gradle properties-file


【解决方案1】:

你可以这样做:

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

如果您正在读取子项目build.gradle 中的属性文件,请使用project.rootProject

.
├── 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

如果属性文件在同一个子项目目录中,您可以只使用project

【讨论】:

  • 什么是“project.rootProject”?
  • 添加了简要说明
  • 项目是什么意思?我的想法给了我一个错误。如何获取项目路径。
  • build.gradle 文件中project 是一个引用当前项目的变量。如果您有奇怪的错误,请提出一个新问题。
  • 如果我将您的代码复制到 app/src/main/java/my_package_name/Utils.java 中的实用程序类中,则无法解析。如何从 Utility 类中读取 local.properties?
【解决方案2】:

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

在代码中,您将其作为资源中的其他字符串 -

resources.getString(R.string.default_account_iccid);

【讨论】:

  • 这是正确答案。怎么没被选中?选择的答案甚至没有提供解决方案??
  • 在我的情况下无法解析符号“属性”
  • 好的,我可以将Properties 声明放在defaultConfig 中吗?为什么人们把它放在defaultConfig 范围之外?
  • 如果我尝试在清单文件中访问这个变量,它不会构建(说找不到资源)
【解决方案3】:

虽然@rciovati 的回答肯定是正确的,但还有另一种读取sdk.dirndk.dir 值的方法。

正如 this blog entry by Gaku Ueda(获取 ndk 目录)中指出的,BasePlugin 类提供了 getNdkFolder()getSdkFolder() 的方法:

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

注意:如果您正在构建库,您可能需要将 com.android.application 更改为 com.android.library

这可能是一种更优雅的读取文件夹值的方式。虽然不得不说@rciovati 提供的答案更加灵活,因为可以读取属性文件中的任何值。

【讨论】:

  • 对于 Gradle 1.1.0,您需要使用 plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder(),如下所示:stackoverflow.com/questions/28615439/…
  • 因转向“实验性”插件而再次崩溃:(
【解决方案4】:

上面手动加载 local.properties 的答案显然有效,下一个要求您知道应用了哪个插件的答案也应该有效。

这些方法对某些人来说可能会更好一些,因为它们更通用,因为无论您使用的是应用程序、测试还是库插件,它们都可以工作。这些 sn-ps 还为您提供对所有 Android 插件配置(产品风味、构建工具版本等)的完全编程访问权限:

如果您需要访问使用 Android Gradle 插件的 build.gradle 文件,只需直接访问 Android DSL,因为它现在可以直接使用:

project.android.sdkDirectory

如果您正在创建自定义 Gradle 任务类或插件,或者只是想查看哪些属性可用,则较长的形式(如下)非常方便。

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

在发布这篇文章时,还有一个方便的 adbExe 属性,绝对值得注意。

此代码必须在根据 Gradle 生命周期配置 Android Gradle 插件之后执行。通常,这意味着您将其放在 Taskexecute 方法中,或者将其放在 Android 应用程序/库的 build.gradle 文件中的 android DSL 声明之后。

这些 sn-ps 还附带一个警告,当您升级 Android Gradle 插件版本时,这些属性可能会随着插件的开发而改变,因此在 Gradle 和 Android Gradle 插件以及 Android Studio 版本之间移动时进行简单的测试(有时新版本的 Android Studio 需要新版本的 Android Gradle 插件)。

【讨论】:

    【解决方案5】:

    我认为这是更优雅的方式。

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

    它适用于 android gradle 1.5.0。

    【讨论】:

      【解决方案6】:

      现在使用the new google plugin 更简单

      1- 添加您的属性

      sdk_dir="sdk dir"
      

      2- 添加插件 (Groovy) this 在顶层(项目级别)

      buildscript {
       dependencies {
           classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0"
       }
      }
      

      在你的应用 Gradle 中

      plugins {
          id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
      }
      

      3- 构建您的项目 4-像这样访问它

      BuildConfig.sdk_dir
      

      【讨论】:

      • 这很简单,不需要 getString() 的上下文
      • 非常感谢!经过一番努力,这成功了
      【解决方案7】:

      添加属性

      以下Gradle 技术向您展示了如何将属性存储在 local.properties 文件中,以便您的应用可以安全地引用它。

      1. 在您的project level 目录中打开local.properties,然后添加您的属性,如下例所示:
      sdk.dir=MY_SDK_DIR
      
      1. 在您的应用级build.gradle 文件中,将此代码添加到defaultConfig 元素中。这允许 Android Studio 在构建时从local.properties 文件中读取sdk.dir 属性,然后将构建变量注入您的res/gradleResVlues.xml
      Properties properties = new Properties()
      if (rootProject.file("local.properties").exists()) {
          properties.load(rootProject.file("local.properties").newDataInputStream())
      }
      
      resValue "string", "sdk_dir", properties.getProperty("sdk.dir", "")
      
      1. 保存文件并将您的项目与 Gradle 同步。
      2. 使用以下代码检索您的字符串
      getString(R.string.sdk_dir);
      

      【讨论】:

      • 这如何与版本控制系统一起工作?您不希望每次更改属性时都创建提交和拉取请求
      • 以同样的方式使用其他方法
      • 还有什么方法?这会在构建期间解决值而不接触源代码吗?
      • 真正的问题是:local.properties 是否包含在您的存储库中?如果是这样,它真的必须是吗?如果仍然是,您将需要对属性文件的任何更改进行版本控制。
      • 没有。它不是,它应该是。我看到了一种方法(我找不到),它从外部属性文件加载属性并将它们添加到buildConfigField,最终在BuildConfig.java 中作为静态最终字段。我认为这比处理 XML 读取等更快。
      【解决方案8】:

      这适用于 Kotlin DSL (build.gradle.kts):

      import java.util.*
      val properties = Properties().apply {
          load(rootProject.file("local.properties").reader())
      }
      val prop = properties.getProperty("propName")
      

      在 Android 项目中,您也可以这样做:

      import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
      val properties = gradleLocalProperties(rootDir)
      val prop = properties.getProperty("propName")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-01
        • 2011-03-10
        • 1970-01-01
        • 1970-01-01
        • 2022-11-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多