網站首頁 編程語言 正文
前言:
在日常的代碼開發(fā)中,此處相信每個開發(fā)人員對代碼質量都是高要求,有自己的一套代碼規(guī)范,但是我們不是單獨作戰(zhàn),往往大家都是團隊作戰(zhàn),人是最大的變量,各人各異,如何保證團隊的代碼質量和代碼規(guī)范呢?靠開發(fā)者自覺嗎?也許有的團隊有嚴格的CR機制,在MR階段會進行CR,CR不通過的MR是不允許合入的,但是這樣會使Reviewer花費較多的時間去校驗,那么這時候我們就需要在編碼過程中提供一種代碼檢測機制。
例如:期望表現(xiàn)的效果就是在編碼時可以展示異常檢測的方法,高亮或者標紅,當鼠標懸停在高亮的代碼上時,會提供問題的描述和解決方法。需要這種效果,就需要自定義lint了。
什么是Lint
在Android Studio中提供的代碼掃描工具Lint,可在無需實際執(zhí)行該應用,也不必編寫測試用例的情況下幫助開發(fā)者發(fā)現(xiàn)代碼質量問題和提出一些改進建議。
Lint工具可檢查您的 Android 項目源文件是否包含潛在錯誤,以及在正確性、安全性、性能、易用性、便利性和國際化方面是否需要優(yōu)化改進。在使用 Android Studio 時,配置的 Lint 和 IDE 檢查會在您每次構建應用時運行。不過,您可以手動運行檢查或從命令行運行 Lint。
android studio內置了較多的lint規(guī)則,但內置的lint規(guī)則無法滿足直觀的適合我們時,就需要我們自定義lint了。
自定義Lint流程:
1. 新創(chuàng)建module,Module類型選擇Java or Kotlin Library, 暫時命名lint_tools
2. 在build.gradle中引入lint的依賴
dependencies {
compileOnly 'com.android.tools.lint:lint-api:27.2.2'
compileOnly 'com.android.tools.lint:lint-checks:27.2.2'
}
在moudle中依賴了lint-api和lint-checks,其中l(wèi)int-api就是lint相關的api,lint-checks就是android studio里自定義的一些lint規(guī)則,我們自定義lint可以參考lint-checks里面的寫法。
3. 本地創(chuàng)建個資源id命名檢查規(guī)則,用來規(guī)范項目中的id統(tǒng)一命名
創(chuàng)建ViewIdDetector,直接繼承LayoutDetector(也可以繼承ResourceXmlDetector 或者 繼承Detector實現(xiàn)的接口是XmlScanner,方式多樣)
import com.android.SdkConstants
import com.android.tools.lint.detector.api.*
import com.android.tools.lint.detector.api.Category.Companion.CORRECTNESS
import com.android.tools.lint.detector.api.Scope.Companion.RESOURCE_FILE_SCOPE
import org.w3c.dom.Element
?
class ViewIdDetector : LayoutDetector() {
override fun getApplicableElements(): Collection<String>? {
return listOf(
SdkConstants.TEXT_VIEW,
SdkConstants.IMAGE_VIEW,
SdkConstants.BUTTON
)
}
?
override fun visitElement(context: XmlContext, element: Element) {
if (!element.hasAttributeNS(SdkConstants.ANDROID_URI, SdkConstants.ATTR_ID)) {
return
}
val attr = element.getAttributeNodeNS(SdkConstants.ANDROID_URI, SdkConstants.ATTR_ID)
val value = attr.value
if (value.startsWith(SdkConstants.NEW_ID_PREFIX)) {
val idValue = value.substring(SdkConstants.NEW_ID_PREFIX.length)
var matchRule = true
var expMsg = ""
when (element.tagName) {
SdkConstants.TEXT_VIEW -> {
expMsg = "tv"
matchRule = idValue.startsWith(expMsg)
}
SdkConstants.IMAGE_VIEW -> {
expMsg = "iv"
matchRule = idValue.startsWith(expMsg)
}
SdkConstants.BUTTON -> {
expMsg = "btn"
matchRule = idValue.startsWith(expMsg)
}
}
if (!matchRule) {
context.report(
ISSUE,
attr,
context.getLocation(attr),
"ViewIdName建議使用view的縮寫_xxx; ${element.tagName} 建議使用 `${expMsg}_xxx`"
)
}
}
}
?
companion object {
val ISSUE: Issue = Issue.create(
"ViewIdCheck",
"ViewId命名不規(guī)范",
"ViewIdName建議使用 view的縮寫加上_xxx,例如tv_xxx, iv_xxx",
CORRECTNESS,
5, Severity.ERROR,
Implementation(
ViewIdDetector::class.java,
RESOURCE_FILE_SCOPE
)
)
}
}
自定義Detector可以實現(xiàn)一個或多個Scanner接口,選擇實現(xiàn)哪種接口取決于你想要的掃描范圍。
Lint API 中內置了很多 Scanner:
Scanner 類型 | Desc |
---|---|
UastScanner | 掃描 Java、Kotlin 源文件 |
XmlScanner | 掃描 XML 文件 |
ResourceFolderScanner | 掃描資源文件夾 |
ClassScanner | 掃描 Class 文件 |
BinaryResourceScanner | 掃描二進制資源文件 |
GradleScanner | 掃描Gradle腳本 |
4. 實現(xiàn)IssueRegistry并添加對應的自定義Issue:
class IMockIssueRegistry: IssueRegistry() {
override val issues: List<Issue>
get() = listOf(
ViewIdDetector.ISSUE
)
?
}
5. 在module(lint_tools)中對應的build.gradle中配置如下信息:
jar {
manifest {
attributes("Lint-registry-v2": "com.imock.lint.IMockIssueRegistry")
}
}
6. 在需要進行l(wèi)int檢查的module中或者app目錄現(xiàn)的build.gradle中引用對應的lint_tools即可使用。
dependencies {
lintChecks project(path: ':lint-tools')
}
至此你可以試著自己自定義Lint了,相關語法api都可參考lint-checks中提供的Detector實現(xiàn),來實現(xiàn)自己的Lint檢查規(guī)則。
拓展一下:
1. 針對Issue.create參數(shù)了解一下:
companion object {
/**
* Creates a new issue. The description strings can use some simple markup;
* see the [TextFormat.RAW] documentation
* for details.
*
* @param id the fixed id of the issue
* @param briefDescription short summary (typically 5-6 words or less), typically
* describing the **problem** rather than the **fix**
* (e.g. "Missing minSdkVersion")
* @param explanation a full explanation of the issue, with suggestions for
* how to fix it
* @param category the associated category, if any
* @param priority the priority, a number from 1 to 10 with 10 being most
* important/severe
* @param severity the default severity of the issue
* @param implementation the default implementation for this issue
* @return a new [Issue]
*/
@JvmStatic
fun create(
id: String,
briefDescription: String,
explanation: String,
category: Category,
priority: Int,
severity: Severity,
implementation: Implementation
): Issue {
val platforms = computePlatforms(null, implementation)
return Issue(
id, briefDescription, explanation, category, priority,
severity, platforms, null, implementation
)
}
}
- 參數(shù)id 唯一的id,簡要表面當前提示的問題。
- 參數(shù)briefDescription 簡單描述當前問題
- 參數(shù)explanation 詳細解釋當前問題和修復建議
- 參數(shù)category 問題類別
- 參數(shù)priority 優(yōu)先級,從1到10,10最重要
- 參數(shù)Severity 嚴重程度:FATAL(奔潰), ERROR(錯誤), WARNING(警告),INFORMATIONAL(信息性),IGNORE(可忽略)
- 參數(shù)Implementation Issue和哪個Detector綁定,以及聲明檢查的范圍。Scope有如下選擇范圍:RESOURCE_FILE(資源文件),BINARY_RESOURCE_FILE(二進制資源文件),RESOURCE_FOLDER(資源文件夾),ALL_RESOURCE_FILES(所有資源文件),JAVA_FILE(Java文件), ALL_JAVA_FILES(所有Java文件),CLASS_FILE(class文件), ALL_CLASS_FILES(所有class文件),MANIFEST(配置清單文件), PROGUARD_FILE(混淆文件),JAVA_LIBRARIES(Java庫), GRADLE_FILE(Gradle文件),PROPERTY_FILE(屬性文件),TEST_SOURCES(測試資源),OTHER(其他);
原文鏈接:https://juejin.cn/post/7084996427662917640
相關推薦
- 2023-10-11 記錄Mybatis-Plus inSql用法
- 2022-05-06 python使用xlrd模塊讀取excel的方法實例_python
- 2022-04-01 簡單聊聊C++中回調函數(shù)的實現(xiàn)_C 語言
- 2022-06-02 Consul的HTTP?API和使用方法_云計算技術
- 2022-05-26 Flutter實現(xiàn)抽屜動畫_Android
- 2022-01-06 解決 el-form 異步校驗導致重復校驗的問題
- 2022-05-21 Nginx實現(xiàn)負載均衡的項目實踐_nginx
- 2022-06-29 Oracle中執(zhí)行動態(tài)SQL_oracle
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支