【问题标题】:Detect IDE environment with Gradle使用 Gradle 检测 IDE 环境
【发布时间】:2014-08-15 10:25:34
【问题描述】:

有没有办法检测我正在运行我的项目的环境。

类似这样的:

build.gradle

def usingIntelliJ = ...
def usingAndroidStudio = ...
if (usingIntelliJ) {
    buildConfigField "String", "IDE_ENV", "IDEA"
} else if (usingAndroidStudio) {
    buildConfigField "String", "IDE_ENV", "AndroidStudio"
}

【问题讨论】:

  • 出于好奇,您为什么要根据您的 IDE 在 Java 中使用不同的行为?
  • 我正在使用 gradle 和 robolectric-gradle-plugin 进行单元测试。我执行命令gradle clean test时的测试运行文件。但是,当我使用 IntelliJ 运行测试时,它不起作用。如果我在 IntelliJ 上运行 System.getProperty("android.manifest") ,结果是空的。所以我知道测试是用 IntelliJ 运行的,我会自己设置属性android.manifest
  • 有什么理由不能只为所有情况设置该属性吗?设置该属性中断测试是否会在 IntelliJ 之外运行?我不排除有一种方法可以检测触发 Gradle 构建的环境,但我的猜测是它充其量只是一个脆弱的解决方案。
  • @CommonsWare 我想我找到了一个用例,希望找出我们是否从 IDE 运行 - 即时运行! :)
  • @CommonsWare 另一个用例是当 IDE 有一个您想要解决的错误,但从命令行运行时该解决方法会中断构建。

标签: android intellij-idea gradle


【解决方案1】:

为了确定您的构建是否由 IDE 触发,Android 构建链将设置一个特定属性:

def isIdeBuild() {
    return project.properties['android.injected.invoked.from.ide'] == 'true'
}

在我们的构建中,我们使用此方法为我们的 IDE 构建设置静态 versionCode,但保留所需的行为以在我们的构建服务器上自动增加它:

def getNumberOfGitCommits() {
    def text = 'git rev-list --count HEAD'.execute().text.trim()
    return text == '' ? 0 : text.toInteger()
}

def calculateVersionCode() {
    return isIdeBuild() ? 123456789 : getNumberOfGitCommits()
}

android {
    defaultConfig {
        // ...
        versionCode calculateVersionCode()
    }
}

这解决了我们遇到的两个问题:

  1. 之前,新提交有效地禁用了 Instant Run。因为 versionCode 是自动更新的,所以 Manifest 发生了变化——这会在 Instant Run 中触发完全重建。
  2. 以前,当我们切换 Git 分支时,versionCode 经常会更改为较小的(降级),因此我们不得不重新安装应用程序。现在,我们的所有 IDE 构建都具有相同的 versionCode。

【讨论】:

  • 我的 IDEA 版本似乎不再设置此属性。它是否停止为您工作@mreichelt?如果是这样,您找到替代方案了吗?
  • @TomClift 仍然适用于我最新的 Android Studio 2.3 和 Android Studio 3.0 Canary 7。Google 本身在其最新的架构组件示例中使用此属性:github.com/googlesamples/android-architecture-components/blob/…您使用的是哪个版本的 IDEA?也许这个属性只存在于 Android Studio 中,而不存在于 IDEA 中。然后你必须找到一个由 IntelliJ IDEA 设置的不同的。
  • 使用 IntelliJ IDEA Ultimate。不知道它什么时候停止工作。测试在 2017.1.5 和 2017.2 上不起作用。提出了替代方案(没有很好地掌握哪些产品/版本适用于哪些产品/版本):ideIdea = System.env.XPC_SERVICE_NAME.contains('intellij') || System.env.XPC_SERVICE_NAME.contains('.idea') || (project.findProperty('android.injected.invoked.from.ide') ?: false) || project.hasProperty('jetExtraModelBuilderClass') XPC_SERVICE_NAME 的一个示例是com.apple.xpc.launchd.oneshot.0x10000001.idea
  • 此属性似乎仅在从 Intellij 运行时存在:if (System.env.IDEA_INITIAL_DIRECTORY == null) {...
  • 只有在你安装了安卓插件的情况下才有效。这在 Android Studio 中始终存在,但在 Intellij 中是可选的。我刚刚删除了 Android 插件,但它停止了工作。
【解决方案2】:

在构建脚本中,您可以评估 IDE 添加的以下属性:

例如:System.getProperty('idea.active')

【讨论】:

    【解决方案3】:

    其他答案对我不起作用,但通过查看所有属性,这些似乎有效:

    • idea.paths.selector - 在默认安装中,它具有诸如“AndroidStudioPreview2021.1”或“IntelliJIdea2021.2”之类的值,因此如果您需要知道它是不是,可以使用它:
    def pathSelector = System.getProperty('idea.paths.selector') ?: ''
    def usingIntelliJ = pathSelector.startsWith('IntelliJIdea')
    def usingAndroidStudio = pathSelector.startsWith('AndroidStudio')
    ...
    
    • idea.platform.prefix - 似乎只为 Android Studio 设置,值为“AndroidStudio”,所以它可能不适用于这种情况,但它是我的解决方案:
    def usingAndroidStudio = System.getProperty('idea.platform.prefix') == 'AndroidStudio'
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 2016-03-31
      • 2015-01-01
      • 1970-01-01
      相关资源
      最近更新 更多