登陆

极彩娱乐测试-仅用5分钟,搞定Android同事所有不规范代码

admin 2019-09-28 119人围观 ,发现0个评论

作者:GitCode8

juejin.im/post/5d307615f265da1b6b1d0dd9

作者:GitCode8

juejin.im/post/5d307615f265da1b6b1d0dd9

前语

曾经对下面的问题,我的情绪是,不报错便是没问题,报错就用快捷键,依据Android Studio提示批改问题,历来不去问个为什么?现在代码洁癖症越来越严峻的我,不由得想看清什么东西在搞鬼。

仔细看完本文,必定能够学到最新的常识。就算看不下去,也要点个赞保藏,绝对不亏。本文并不是吐槽Lint的欠好,而是在学习Lint进程碰到问题,心态是奔溃的,以及处理每个问题带来的喜感。

不知道咱们有没有留意项目中黄色代码块的提示,如下图所示:

或许赤色符号的代码(并没有任何过错),如下图所示:

上文黄色的提示和赤色正告,都是来自Android Studio内置的Lint东西查看咱们的代码后而作出的动作。经过装备Lint,也能够消除上面的提示。例如,我开发体系APK,底子不需求考虑用户是否授权。那么Lint是什么呢?

Lint

Android Studio 供给一个名为Lint的静态代码扫描东西,能够发现并纠正代码结构中的质量问题,而无需实践履行该运用,也不必编写测验用例。Lint 东西可查看您的 Android 项目源文件是否包括潜在过错,以及在正确性、安全性、功能、易用性、便利性和国际化方面是否需求优化改善。

Android Studio 供给一个名为Lint的静态代码扫描东西,能够发现并纠正代码结构中的质量问题,而无需实践履行该运用,也不必编写测验用例。Lint 东西可查看您的 Android 项目源文件是否包括潜在过错,以及在正确性、安全性、功能、易用性、便利性和国际化方面是否需求优化改善。

也便是说,经过Lint东西,咱们能够写出更高质量的代码和代码潜在的问题,妈妈再也不必忧虑我的搭档用中文命名了。也能够经过定制Lint相关装备,进步开发功率。

Lint制止查看

由于Android Studio内置了Lint东西,如同不需求咱们干嘛。可是呀,我有强迫症,看着上面的黄色块,超级不爽的。所以咱们得了解怎么装备Lint,让它为咱们服务,而不是为Google服务。

本文开端的赤色过错能够经过注解来消除(一般主张是依据提示进行批改,除非了解自己在做什么),能够在类或该代码地点的办法增加@SuppressLint

上图中是制止Lint查看特定的问题查看,假如要制止该Java文件一切的Lint问题,能够在类前增加如下注解:@SuppressLint(all)。对XMl文件的制止,则能够选用如下方式:

  1. 在lint.xml声明命名空间

namespacexmlns: tools= "http://schemas.android.com/tools"

  1. 在布局中运用:

<LinearLayout

xmln s:android= "http://schemas.android.com/apk/res/android"

xmln s:tools= "http://schemas.android.com/tools"

tool s:ignore= "UnusedResources">

<TextView

android:text= "@string/auto_update_prompt"/>

</LinearLayout>

父容器声明晰ignore特点,那么子视图会承继该特点。例如上文LinearLayout中声明晰制止Lint查看LinearLayout的UnusedResources问题,TextView天然也制止查看该问题。制止查看多个问题,问题之间用逗号离隔;制止查看一切问题则运用all关键字。

tool s:ignore= "all"

咱们也能够经过装备项目的Gradle文件来制止查看。

例如制止Lint查看项目AndroidManifest.xml文件的GoogleAppIndexingWarning问题。在项目对应组件工程的Gradle文件增加如下装备,这样就不会有黄色提示了。

defaultConfig{

lintOptions {

disable'GoogleAppIndexingWarning'

}

}

那么,能够制止lint东西查看什么问题?

装备Lint

在上文中经过注解和在xml运用特点来制止Lint东西查看相关问题,其完成已是对Lint的装备了。Lint将多个问题归为一个issue(规矩),例如下图右边的的六大规矩。

上图是Lint东西的作业流程,下面了解相关概念。App Source Files源文件包括组成 Android 项目的文件,包括 Java 和 XML 文件、图标和 ProGuard 装备文件等。lint.xml 文件此装备文件可用于指定您期望扫除的任何 Lint 查看以及自界说问题严峻等级。lint Tool咱们能够经过Android Studio 对 Android 项目运转此静态代码扫描东西。也能够手动运转。Lint 东西查看或许影响 Android 运用质量和功能的代码结构问题。Lint 查看成果咱们能够在控制台(指令行运转)或 Android Studio 的 Inspection Results 窗口中查看 Lint 查看成果。

经过Lint东西的作业流程了解到,能够在lint.xml文件装备一些信息。一般新建项目都是没有lint.xml文件的,在项目的根目录创立lint.xml文件。格局如下:

<?xml version="1.0"encoding="UTF-8"?>

<lint>

<!-- list of issues to configure -->

</lint>

那么有哪些Issues(规矩)呢?

在Android首要有如下六大类:

  • Security 安全性。在AndroidManifest.xml中没有装备相关权限等。
  • Usability 易用性。重复图标;上文开端黄色正告也归于该规矩等。
  • Performance 功能。内存走漏,xml结构冗余等。
  • Correctness 正确性。超版别调用API,设置不正确的特点值等。
  • Accessibility 无障碍。单词拼写过错等。
  • Internationalization国际化。字符串短少翻译等。

其他更多Issues,能够通将指令行切换到../Android/sdk/tools/bin目录下,然后输入lint --list。例如在Mac下:cd /Users/gitcode8/Library/A嘻哈包袱铺ndroid/sdk/tools/bin输入./lint --list成果如下:

例如官网供给的参阅比如:

<?xml version极彩娱乐测试-仅用5分钟,搞定Android同事所有不规范代码="1.0"encoding="UTF-8"?>

<lint>

<!-- 疏忽整个工程目录下指定问题的查看 -->

<issueid="IconMissingDensityFolder"s极彩娱乐测试-仅用5分钟,搞定Android同事所有不规范代码everity="ignore"/>

<!-- 疏忽对指定文件指定问题的查看 -->

<issueid="ObsoleteLayoutParam">

<ignorepath="res/layout/activation.xml"/>

<ignorepath="res/layout-xlarge/activation.xml"/>

</issue>

<!-- 更改查看问题归属的严峻性 -->

<issueid="HardcodedText"severity="error"/>

</lint>

学习Lint东西只是是为了安慰我的强迫症?不,还不知道Lint真实用来干嘛呢?

查看项目质量

欠好简略开发了个APP,预备开端上班摸鱼了。还让代码自查?那就经过Lint来看看代码质量怎么吧。

  1. 经过Android Studio 的菜单栏Analyze选项下拉挑选第一个选项Insp极彩娱乐测试-仅用5分钟,搞定Android同事所有不规范代码ect Code.

2、在弹出框依据自己需求挑选lint东西的查看规模,这儿挑选整个项目。查看时刻也是依据项目巨细来定的。

3、等候一段时刻后,会列出查看成果。从下图看到,不只会查看Android存在的问题,也会查看Java等其他问题。经过单击问题,能够从右边提示框看到问题发作的当地和相关主张。

到这儿,就开端对项目修修补补吧。

在正式开刷之前不得不说到:自界说规矩为什么要自界说呢? 已有规矩不契合自己或团队开发需求,或许觉得Lint存在一些缺点。在网上大多数文章千人一面,都是经过将Log打印来举例,看着都好累哦。由于没有相关官方文档和第三方教程(或许由于lint的api更新太快,没人乐意做这种吃力不讨好的作业),也这就只要这样了。本文经过自界说命名标准规矩来解说整个进程。

自界说规矩

为什么要自界说呢?已有规矩不契合自己或团队开发需求,或许觉得Lint存在一些缺点。在网上大多数文章千人一面,都是经过将Log打印来举例,看着都好累哦。由于没有相关官方文档和第三方教程(或许由于lint的api更新太快,没人乐意做这种吃力不讨好的作业),也这就只要这样了。本文经过自界说命名标准规矩来解说整个进程。

Lint中要点的API

先学习相关api,能够快速了解一些概念,能够大略看过,下面结实践再回来看。

1、Issue

Issue如上文所说,表明lint 东西查看的一个规矩,一个规矩包括若干问题。常在Detector中创立。下文是创立一个Issue的比如。

privatestaticfinalIssue ISSUE = Issue.create( "NamingConventionWarning",

"命名标准过错",

"运用驼峰命名法,办法命名最初小写,类大写字母最初",

Category.USABILITY,

5,

Severity.WARNING,

newImplementation(NamingConventionDetecor.class,

EnumSet.of(Scope.JAVA_FILE)));

  • 第一个参数id 仅有的id,扼要外表当时提示的问题。
  • 第二个参数briefDeion 简略描绘当时问题
  • 第三个参数explanation 详细解说当时问题和批改主张
  • 第四个参数category 问题类别,例如上文讲到的Security、Usability等等。
  • 第五个参数priority 优先级,从1到10,10最重要
  • 第六个参数Severity 严峻程度:FATAL(奔溃), ERROR(过错), WARNING(正告),INFORMATIONAL(信息性),IGNORE(可疏忽)
  • 第七个参数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(其他);

这样就能很清楚的界说一个规矩,上文只界说了查看命名标准的规矩。

2、IssueRegistry

用于注册要查看的Issue(规矩),只要注册了Issue,该Issue才干被运用。例如注册上文的命名标准规矩。

publicclassRegisterextendsIssueRegistry{

@NotNull

@Override

public List<Issue> getIssues {

returnArrays.asList(NamingConventionDetector.ISSUE);

}

}

4、Detector

查找指定的Issue,一个Issue对应一个Detector。自界说Lint 规矩的进程也便是重写Detector类相关办法的进程。详细看下小结实践。

5、Scanner

扫描并发现代码中的Issue,Detector需求完成Scaner,能够承继一个到多个。

  • UastScanner 扫描Java文件和Kotlin文件
  • ClassScanner 扫描Class文件
  • XmlScanner 扫描Xml文件
  • ResourceFolderScanner 扫描资源文件夹
  • BinaryResourceScanner 扫描二进制资源文件
  • OtherFileScanner 扫描其他文件
  • GradleScanner 扫描Gradle脚本

旧版别的JavaScanner、JavaPsiScanner跟着版别的更新现已被UastScanner代替了。

自界说Lint规矩实践

经过完成命名标准Issue来了解和运用上末节相关的api。自界说规矩需求在Java工程中创立,这儿经过Android Studio来创立一个Java Library。

过程:File->New->New Mudle->Java Library

这儿Library Name为lib。

界说类NamingConventionDetector,并承继自Detector。由于这儿是检测Java文件类名和办法是否契合规矩,所以完成Detector.UastScanner接口。

publicclassNamingConventionDetector

extendsDetector

implementsDetector.UastScanner{

}

在NamingConventionDetector类内界说上文的Issue:

publicclassNamingConventionDetector

extendsDetector

implementsDetector.UastScanner{

publicstaticfinalIssue ISSUE = Issue.create( "NamingConventionWarning",

"命名标准过错",

"运用驼峰命名法,办法命名最初小写",

Category.USABILITY,

5,

Severity.WARNING,

newImplementation(NamingConventionDetector.class,

EnumSet.of(Scope.JAVA_FILE)));

}

重写Detector的createUastHandler办法,完成咱们自己的处理类。

publicclassNamingConventionDetectorextendsDetectorimplementsDetector.UastScanner{

//界说命名标准规矩

publicstaticfinalIssue ISSUE = Issue.create( "NamingConventionWarning",

"命名标准过错",

"运用驼峰命名法,办法命名最初小写",

Category.USABILITY,

5,

Severity.WARNING,

newImplementation(NamingConventionDetector.class,

EnumSet.of(Scope.JAVA_FILE)));

//回来咱们一切感兴趣的类,即回来的类都被会查看

@Nullable

@Override

publicList<Class<? extends UElement>> getApplicableUastTypes {

returnCollections.<Class<? extends UElement>>singletonList(UClass.class);

}

//重写该办法,创立自己的处理器

@Nullable

@Override

publicUElementHandler createUastHandler(@NotNull finalJavaContext context){

returnnewUElementHandler {

@Override

publicvoidvisitClass(@NotNull UClass node){

node.accept( newNamingConventionVisitor(context, node));

}

};

}

//界说一个承继自AbstractUastVisitor的拜访器,用来处理感兴趣的问题

publicstaticclassNamingConventionVisitorextendsAbstractUastVisitor{

JavaContext context;

UClass uClass;

publicNamingConventionVisitor(JavaContext context, UClass uClass){

this.context = context;

this.uClass = uClass;

}

@Override

publicbooleanvisitClass(@org.jetbrains.annotations.NotNull UClass node){

//获取当时类名

charbeginChar = node.getName.charAt( 0);

intcode = beginChar;

//假如类名不是大写字母,则触碰Issue,lint东西提示问题

if( 97< code && code < 122) {

context.report(ISSUE,context.getNameLocation(node),

"the name of class must start with uppercase:"+ node.getName);

//回来true表明触碰规矩,lint提示该问题;false则不触碰

returntrue;

}

returnsuper.visitClass(node);

}

@Override

publicbooleanvisitMethod(@NotNull UMethod node){

//当时办法不是结构办法

if(!node.isConstructor) {

charbeginChar = node.getName.charAt( 0);

intcode = beginChar;

//当时办法首字母是大写字母,则报Issue

if( 65< code && code < 90) {

context.report(ISSUE, context.getLocation(node),

"the method must start with lowercase:"+ node.getName);

//回来true表明触碰规矩,lint提示该问题;false则不触碰

returntrue;

}

}

returnsuper.visitMethod(node);

}

}

}

上文NamingConventionDetector类,现已是悉数代码,只查看类名和办法名是否契合驼峰命名法,能够依据详细需求,重写抽象类AbstractUastVisitor的visitXXX办法。

假如处理特定的办法或许其他,也能够运用默许的处理器。重写Scanner相关办法。例如:

@Override

publicList< String> getApplicableMethodNames {

returnArrays.asList( "e", "v");

}

表明e,v办法会被检测到,并调用visitMethod办法,完成自己的逻辑。

@Override

publicvoidvisitMethod JavaContext context, JavaElementVisitor visitor, PsiMethodCallExpression call, PsiMethod method) {

//todo something

super.visitMethod(context, visitor, call, method);

}

接下来便是注册自界说的Issue:

publicclassRegisterextendsIssueRegistry{

@NotNull

@Override

publicList<Issue> getIssues{

returnArrays.asList(NamingConventionDetector.ISSUE);

}

}

在lib项目的build.gradle文件增加相关代码:

applyplugin: 'java-library'

dependencies {

implementationfileTree(dir: 'libs', include: [ '*.jar'])

implementation 'com.android.tools.lint:lint-api:26.4.2'

implementation 'com.android.tools.lint:lint-checks:26.4.2'

}

//增加如下代码

jar {

manifest{

attributes'Lint-Registry': 'com.gitcode.lib.Register'

}

}

sourceCompatibility = "7"

targetCompatibility = "7"

到这儿就自界说Lint自界说规矩就搞定了,接着是运用和确认规矩是否正确。

运用自定Lint规矩

运用自界说Lint规矩有两种方式:jar包和AAR文件。

jar方式运用

在Android Studio的Terminal输入下面指令:

./gradlew li b:assemble

看到BUILD SUCCESSFUL则表明生成jar包成功,能够鄙人面途径找到:

lib->build->libs

如图:

将lib.jar复制下面目录:

~ /.android/lint/

假如lint文件夹不存在,则创立。经过指令行输入lint --list。滑到最终能够看到装备的规矩,如图:

重启Android Studio,让规矩收效。检测到办法大写,不契合命名标准,报道该问题。

类名不契合标准:

从上文能够看到,放在目录下的jar包对一切工程都是有用的。假如要针对单个工程,那么就需求需求AAR方式了。

AAR方式

在同个工程新建一个Android Library,名为lintLibrary,修正相关装备。

1、修正Java工程的依靠

修正自界说lint规矩的Java库的build.gradle(这儿是上文的Java lib库),留意到要将implementation改为compileOnly。

applyplugin: 'java-library'

dependencies {

implementationfileTree(dir: 'libs', include: [ '*.jar'])

//将implementation改为compileOnly,否则报错

compileOnly 'com.android.tools.lint:lint-api:26.4.2'

compileOnly 'com.android.tools.lint:lint-checks:26.4.2'

}

jar {

manifest{

attributes'Lint-Registry-v2': 'com.gitcode.lib.Register'

}

}

sourceCompatibility = "7"

targetCompatibility = "7"

2、修正Android Library依靠

Android Library首要用来输出AAR文件,要留意到Android Studio新特性的改变(在这儿踩了大坑)。

dependencies{

......

lintPublishproject( ':lib')

}

在Android Studio 3.4+,lintChecks project(':lib'):lint查看只在当时工程收效,也便是Android Library,并不会打包到AAR文件中。lintPublish project(':lib')才会将lint查看包括AAR文件中。

3、输出AAR文件

此刻跟输出一般的AAR文件没什么差异,但为了手把手教会第一个自界说Issue,我写!

过程:

菜单栏:View->Tool Windows->Gradle

菜单栏:View->Tool Windows->Gradle

此刻Android Studio在右边会翻开如下窗口:

依据上图操作,双击assemble,稍等一会,在控制台看BUILD SUCCESSFUL,则可鄙人面目录找到AAR文件。

lintLibrary->build->outputs->aar

这一末节的过程也能够经过指令行履行。

4、运用AAR文件

有本地依靠或许上传长途库房,这儿只介绍本地依靠。将上小结生成的AAR文件复制在app的libs文件夹。并装备app组件的build.gradle

repositories{

flatDir{

dirs'libs'

}

}

dependencies {

implementation(name: 'lintlibrary-release', ext极彩娱乐测试-仅用5分钟,搞定Android同事所有不规范代码: 'aar')

}

到这儿,就能运用自界说的lint规矩了,作用和上面运用jar包是共同的。假如不收效,重启Android Studio看看。

采坑记

1、Found more than one jar in the 'lintChecks' configuration. Only one file is supported

这是由于在输出AAR文件中,参阅其他人的文章。没有将Java Library的依靠改为compileOnly。并且Android Library中运用lintChecks

2、输出AAR文件没有收效

不知道为什么,Linkedin的参阅文章没有收效(https://engineering.linkedin.com/android/writing-custom-lint-checks-gradle),或许是Android Studio版别的问题。

别的运用lintChecks输出AAR不收效,Android Studio 3.4+新特性改变,选用lintPublish(AGP 3.4+)。

总结

花了好长好长的时刻写本文,差点就抛弃了。由于自己Android Studio看不了lint的源码,只能从网上找,网上又找不到最新的doc。过滤太多相同文章,差点想哭,一些最新的文章也跟不上相关技能的更新。。。

可是一切都值得,由于能协助到想学习Android Studio lint东西的同学,一同神往夸姣的日子。

https://github.com/GitCode8/blob

  • 极彩娱乐测试-唏嘘!700亿破产没完 贾跃亭被曝请求离婚!刚转了360万家庭抚养费
  • 请关注微信公众号
    微信二维码
    不容错过
    Powered By Z-BlogPHP