选择 Java or Kotlin 类型
我自己项目中测试使用 3.x.x 版本 依赖下载不下来,我用了最新的 2.x.x 版本
// https://mvnrepository.com/artifact/com.android.tools.lint/lint-api
implementation "com.android.tools.lint:lint-api:27.2.2"
implementation "com.android.tools.lint:lint-checks:27.2.2"
class ToastDetector : Detector(), Detector.UastScanner {
override fun getApplicableMethodNames(): List<String> {
// 指定方法名
return listOf("makeText")
}
override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
// 找到指定方法的类
if (method.containingClass?.qualifiedName == "android.widget.Toast") {
context.report(
ISSUE,
node,
context.getLocation(node),
"使用 `toast()` `toastShort()` `toastLong()`"
)
}
}
companion object {
val ISSUE: Issue = Issue.create(
id = "ToastUsage", // `lint.xml` 配置用的是这个 id
briefDescription = "使用工具类的 Toast",
explanation = "使用 `toast()`",
category = Category.CORRECTNESS,
severity = Severity.WARNING,
implementation = Implementation(
ToastDetector::class.java,
Scope.JAVA_FILE_SCOPE
)
)
}
}
创建一个类,实现 IssueRegistry 的 issues
class MyIssueRegistry : IssueRegistry() {
override val issues: List<Issue> = listOf(
ToastDetector.ISSUE,
LogDetector.ISSUE,
) // 将所有自定义 Lint 的 ISSUE 列出
}
然后在模块的 build.gradle.kts 注册上面的类
// kotlin dsl
tasks.jar {
manifest {
// `Lint-Registry` 是 lint 的注册类
// 注册 IssueRegistry 的实现类
attributes("Lint-Registry" to "com.example.test.module_lint.MyIssueRegistry")
}
}
// groovy
jar {
manifest {
// `Lint-Registry` 是 lint 的注册类
// 注册 IssueRegistry 的实现类
attributes('Lint-Registry': 'com.example.test.module_lint.MyIssueRegistry')
}
}
可以放到 项目根目录 或 模块根目录,位置就是检查的有效范围
这个 task 的目的是在 Java 的 MANIFEST.MF 添加相关信息,而不是 AndroidManifest.xml
在 build.gradle 中添加 Lint 检查的依赖
dependencies {
lintChecks project(':module_lint')
}
在根目录创建 lint.xml
<lint>
<!-- severity="ignore" 禁用 -->
<issue id="ToastUsage" severity="error" />
<issue id="LogUsage" severity="warning"/>
</lint>
这个文件可以方便统一配置多个检查器
在 lint 定义的模块 build.gradle 增加以下内容
// 定义 lintJarOutput,在 module_lint_aar 中被调用
val lintJarOutput by configurations.creating
dependencies {
// ...
// 将 jar 文件添加到 lintJarOutput
lintJarOutput(files(tasks.jar.get().archiveFile))
}
新建一个 Android Library 模块(只用作打包 aar,多余的东西都可以删了)
plugins {
alias(libs.plugins.android.library)
}
android {
namespace = "com.example.test.module_lint_aar"
compileSdk = 35
defaultConfig {
minSdk = 21
}
}
dependencies {
// 调用 module_lint 的 lintJarOutput,获得 jar 包
lintPublish(project(path = ":module_lint", configuration = "lintJarOutput"))
}
然后 build 一下就可以产出 aar 文件了
这里 aar 文件需要使用 implement 引用才能正常工作
再贴一下基于 groovy 语言的传统 build.gradle 文件
Java Library
// 定义 lintJarOutput,在 module_lint_aar 中被调用
configurations {
lintJarOutput
}
dependencies {
// 将 jar 文件添加到 lintJarOutput
lintJarOutput files(jar)
}
Android Library
dependencies {
// 调用 module_lint 的 lintJarOutput,获得 jar 包
lintPublish project(path: ":module_lint", configuration: "lintJarOutput")
}
implementation(files("libs/module_lint_aar-debug.aar")) // 使用 aar,这里要用 implementation,测试过 lintChecks 是不行的
// lintChecks(project(":module_lint")) // 这个是直接使用模块源码
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
`maven-publish`
}
android {
// ...
buildTypes {
release {
// ...
}
}
}
// android module 的 publishing 需要放到 afterEvaluate 里面
afterEvaluate {
publishing {
publications {
// android
create<MavenPublication>("maven") {
from(components["release"])
// 设置 Maven 坐标
groupId = "your.group"
artifactId = "lint"
version = "1.0.0"
}
}
repositories {
mavenLocal() // 发布到本地 Maven 仓库
}
}
}
在模块目录执行命令,就可以发布到本地 maven 了
../gradlew publishToMavenLocal