构建Android Studio项目时运行lint

52

我希望能够在使用Android Studio构建项目时运行lint任务,以确保遵循lint规则。

我尝试过使用任务依赖关系,但没有成功。我的TeamCity构建服务器使用构建任务来运行lint任务,所以那个做得很好。然而,当我选择调试版本时,Android Studio似乎会交替使用generateDebugSourcescompileDebugJava任务。

这是我在build.gradle中尝试的内容:

assemble.dependsOn lint
8个回答

44

如果你只是想在Android Studio项目默认运行配置之前配置lint检查,而不影响gradle任务的设置,可以按照以下步骤操作。

  1. 打开运行配置下拉菜单并选择编辑

enter image description here

  1. 选择您的应用程序运行配置

enter image description here

  1. 点击"+"以添加新的步骤

enter image description here

  1. 选择“Gradle-aware Make”

enter image description here

  1. 键入“check”,并选择带有您的应用程序模块名称和check选项的选项。 (我的是:app:check

enter image description here

  1. 按上箭头将新的check步骤移动到现有的Gradle-aware make步骤之前

enter image description here

现在,Android Studio将运行lint检查,并在出现任何lint错误时失败构建。


5
可以这样做,但理想情况下我不希望项目中的每个人都必须以这种方式设置他们的环境。有没有一种使用Gradle完成这项任务的方法? - Robert
由于这是最接近我实际想要的,所以我现在将其标记为正确答案。 - Robert
2
我们能否在Gradle构建中设置这个东西? - Ewoks
你可以在gradle上设置这个,有点像是一个hack但是可行。思路是让assemble任务依赖于lint任务,这样每次运行时都会运行lint。我在下面的答案中编写了代码。 - Yoel Gluschnaider

39

要运行代码检查和分析,请选择Analyze > Inspect Code

您应该看到一个包含所有问题的漂亮窗口。

enter image description here

如需更多信息,请查看在Android Studio中运行lint


我进行了更多研究,请尝试将此内容添加到您的build.gradle文件中。

lintOptions {
      abortOnError true
  } 

你可以对 build.gradle 应用许多选项


5
我希望你能翻译以下内容:我希望防止在任何 Lint 错误的情况下编译项目,以确保遵循 Lint 规则。仅运行代码检查可能会被忽略,并不能保证在编译时遵循 Lint 规则。 Translated: 我想防止在任何 Lint 错误的情况下编译项目,以确保遵循 Lint 规则。进行代码检查可能会被忽略,不能保证在编译时遵循 Lint 规则。 - Robert
1
我该如何在我的build.gradle文件中添加一个lint调用? - Robert
3
我已经在使用 abortOnError,这就是为什么我的构建服务器会中断构建的原因。Android Studio 在构建项目时不会运行 lint 任务。我应该如何在构建项目时运行 lint 任务? - Robert
你能否直接调用构建服务器?请参考https://dev59.com/jGIk5IYBdhLWcg3wKLSd。 - Andrew Gable
建立不同的变体如何解决我的问题还不清楚。 - Robert
3
我不想手动运行“lint(代码检查)”任务,我希望在构建项目时自动运行它。 - Robert

28
在build.gradle中完成此操作,请将以下行添加到您的build.gradle中:
android {
  applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def lintTask = tasks["lint${variant.name.capitalize()}"]
        output.assemble.dependsOn lintTask
    }
  }
  ...
}
这使得你所有的组装任务都依赖于 lint 任务,在 Android Studio 执行每个 assemble 调用之前有效地运行它们。 编辑 使用 Android Gradle 插件 3.3 和 Gradle 5.x,这是一个使用 Kotlin 脚本修订过的版本:
applicationVariants.all {
  val lintTask = tasks["lint${name.capitalize()}"]
  assembleProvider.get().dependsOn.add(lintTask)
}

当我使用Android Studio的播放按钮(运行'app')时,它对我有用,但是当我使用“Make Project”按钮时却不起作用。 - Travis
1
@Travis,说实话我不了解Make Project。据我所知,它应该运行assemble命令,其依赖于lint命令。但我可以再试一次。 - Yoel Gluschnaider
1
@RushabhShah - 这是 Kotlin 脚本对吧?如果是 Groovy,使用 def 代替 val - Yoel Gluschnaider
@NikhilKatekhaye - 不确定我理解你在这里的评论... - Yoel Gluschnaider
重建项目后,未使用的方法和未使用的数据类型不会被删除。 - Nikhil Katekhaye
显示剩余4条评论

12

只需运行“check”任务

./gradlew clean check assembleRelease

1
这回答了如何从命令行而不是从Android Studio运行检查任务。 - Robert
这是最佳答案,因为你也可以在Jenkins中实现。谢谢。 - Alejandro Zurcher
4
这可能是对一个不同问题的最佳答案。 - Yoel Gluschnaider

6

以下是我的解决方案,可适用于在Android Studio中点击BuildMake Project的情况:

android {
..
    afterEvaluate {
        applicationVariants.all {
            variant ->
                // variantName: e.g. Debug, Release
                def variantName = variant.name.capitalize()
                // now we tell gradle to always start lint after compile
                // e.g. start lintDebug after compileDebugSources
                project.tasks["compile${variantName}Sources"].doLast {
                    project.tasks["lint${variantName}"].execute()
                }
        }
    }
}

非常好的答案!这正是我在寻找的。然而,它给了我以下错误信息:“在类型为com.android.build.gradle.tasks.LintPerVariantTask的任务':app:lintDebug'上未找到参数[]的execute()方法。” - Saran Sankaran
谢谢!你救了我的命! - Alberto
Gradle最近的版本中已经移除了execute方法,这里是一个适用于我的替代方案:project.tasks["compile${variantName}Sources"].dependsOn("lint${variantName}") - Sofien Rahmouni

5

如果你想在不影响gradle任务配置的情况下,强制让Android Studio项目在默认运行配置之前运行lint检查,并且你想在gradle构建系统中完成这个操作,那么你可以按照以下方式,在应用程序模块的build.gradle文件中,在android块外面添加以下代码块:

android {
....
    lintOptions {
        abortOnError true
    }
}

tasks.whenTaskAdded { task ->
    if (task.name == 'compileDevDebugSources') {
        task.dependsOn lint
        task.mustRunAfter lint
    }
}

compileDevDebugSources 替换为您已经定义的所需构建变量,例如:compileReleaseSourcescompileDebugSourcescompileStagingDebugSources 等。

此方法在 Android Studio 3.0 上已测试有效。


我如何将此应用于所有构建变体,而无需列出所有任务名称? - manfcas

4

我只是修改了@Yoel Gluschnaider的回答。

对我来说,如果我使用Val,会显示以下错误: 无法为类型com.android.build.gradle.internal.api.ApplicationVariantImpl的对象设置未知属性“lintTask”。

所以我进行了替换。

applicationVariants.all {
    def lintTask = tasks["lint${name.capitalize()}"]
    assembleProvider.get().dependsOn.add(lintTask)
}

并且它正常运作!

2
我为Kotlin脚本编写了我的答案。这是Groovy :) - Yoel Gluschnaider

1

更高效的答案如下所示 Gradle 任务配置避免

Gradle kts 版本

android {
    applicationVariants.configureEach {
        val variantName =
            name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.ENGLISH) else it.toString() }
        val lintTaskName = "lint$variantName"
        val lintTask = tasks.named("lint$variantName")
        assembleProvider.dependsOn(lintTask, tasks.named("detekt$variantName"))
    }
}

时髦版本
android {
    applicationVariants.configureEach {
        def variantName = name.capitalize()
        def lintTaskName = "lint$variantName"
        def lintTask = tasks.named("lint$variantName")
        assembleProvider.configure {
            dependsOn lintTask
        }
    }
}

优点:
  1. 没有调用assembleProvider.get(),这违背了避免配置的目的
  2. 使用命名函数访问Lint任务,只有在需要时才会延迟访问任务(在Gradle迁移指南guide中提到)
  3. 使用configureEach,在需要时配置每个任务,而不是急切地配置

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接