首页 > 解决方案 > 我们如何为我们的应用程序编写自定义 lint 规则?

问题描述

我使用此链接创建我们自己的自定义 lint 规则 链接

然后创建WrongLayoutDetector.class以检测错误的布局名称

private val allowedPrefixes = listOf("activity_", "view_", "fragment_", "dialog_", "bottom_sheet_", "adapter_item_", "divider_", "space_", "popup_window_")

val ISSUE_WRONG_LAYOUT_NAME = Issue.create("WrongLayoutName",
    "Layout names should be prefixed accordingly.",
    "The layout file name should be prefixed with one of the following: ${allowedPrefixes.joinToString()}. This will improve consistency in your code base as well as enforce a certain structure.",
        CORRECTNESS, 7, WARNING,
    Implementation(WrongLayoutNameDetector::class.java, RESOURCE_FILE_SCOPE))

class WrongLayoutNameDetector : LayoutDetector() {
  override fun visitDocument(context: XmlContext, document: Document) {
    val modified = allowedPrefixes.map {
      val resourcePrefix = context.project.resourcePrefix()
          .forceUnderscoreIfNeeded()

      if (resourcePrefix != it) resourcePrefix + it else it
    }

    val doesNotStartWithPrefix = modified.none { context.file.name.startsWith(it) }
    val notEquals = modified.map {
        it.dropLast(1) // Drop the trailing underscore.
    }.none { context.file.name == "$it.xml" }

    if (doesNotStartWithPrefix && notEquals) {
      context.report(ISSUE_WRONG_LAYOUT_NAME, document, context.getLocation(document), "Layout does not start with one of the following prefixes: ${modified.joinToString()}")
    }
  }
}

private fun String.forceUnderscoreIfNeeded() = if (isNotEmpty() && !endsWith("_")) plus("_") else this

fun Project.resourcePrefix() = if (isGradleProject) computeResourcePrefix(gradleProjectModel).orEmpty() else ""

问题注册表类

class IssueRegistry : IssueRegistry() {
    override val issues: List<Issue>
        get() = listOf( ISSUE_WRONG_LAYOUT_NAME,ISSUE_ALERT_DIALOG_USAGE)

    override val api: Int = com.android.tools.lint.detector.api.CURRENT_API
}

构建 gradle 文件

apply plugin: 'java-library'

dependencies {
    // For a description of the below dependencies, see the main project README
    compileOnly "com.android.tools.lint:lint-api:26.2.0-rc02"
    compileOnly "com.android.tools.lint:lint-checks:26.2.0-rc02"
    testCompile "junit:junit:4.12"
    testCompile "com.android.tools.lint:lint:26.2.0-rc02"
    testCompile "com.android.tools.lint:lint-tests:26.2.0-rc02"
    testCompile "com.android.tools:testutils:26.2.0-rc02"
}

sourceCompatibility = "1.8"
targetCompatibility = "1.8"

jar {
    manifest {
        // Only use the "-v2" key here if your checks have been updated to the
        // new 3.0 APIs (including UAST)
        attributes("Lint-Registry-v2": "com.example.lint.checks.IssueRegistry")
    }
}

现在在我们的代码中

lint.xml 文件

<lint>
     <!-- Change the severity of hardcoded strings to "error" -->
    <issue id="WrongLayoutName"
  severity="warning"  />
</lint>

并在应用程序 gradle 文件中

 lintOptions {
        tasks.lint.enabled = true
        abortOnError true
        lintConfig file('./code_quality_tools/lint.xml')
    }

现在我正在分析代码,但没有收到像 WrongLayoutName 这样的警告。我如何使用我们的应用程序实现自定义 lint 规则?

如果我 <issue id="AllCaps" />在 lint 文件中添加它的工作正常并收到警告

标签: android

解决方案


您必须在依赖项中添加链接检查模块:

如果你有这个结构:

lint-check
   -- build.gradle
app
   -- build.gradle
settings.gradle

settings.gradle

include ':app'
include ':lint-checks'

app/build.gradle

dependencies {
    lintChecks project(':lint-checks')
}

推荐阅读