2024年安卓最全代码洁癖症的我,学习 Lint 学到心态爆炸,2024Android精选面试实战总结整理

最后

有任何问题,欢迎广大网友一起来交流,分享高阶Android学习视频资料和面试资料包~

偷偷说一句:群里高手如云,欢迎大家加群和大佬们一起交流讨论啊!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 第五个参数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才能被使用。例如注册上文的命名规范规则。

public class Register extends IssueRegistry {

@NotNull

@Override

public List getIssues() {

return Arrays.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接口。

public class NamingConventionDetector

extends Detector

implements Detector.UastScanner {

}

在NamingConventionDetector类内定义上文的Issue:

public class NamingConventionDetector

extends Detector

implements Detector.UastScanner {

public static final Issue ISSUE = Issue.create(“NamingConventionWarning”,

“命名规范错误”,

“使用驼峰命名法,方法命名开头小写”,

Category.USABILITY,

5,

Severity.WARNING,

new Implementation(NamingConventionDetector.class,

EnumSet.of(Scope.JAVA_FILE)));

}

重写Detector的createUastHandler方法,实现我们自己的处理类。

public class NamingConventionDetector extends Detector implements Detector.UastScanner {

//定义命名规范规则

public static final Issue ISSUE = Issue.create(“NamingConventionWarning”,

“命名规范错误”,

“使用驼峰命名法,方法命名开头小写”,

Category.USABILITY,

5,

Severity.WARNING,

new Implementation(NamingConventionDetector.class,

EnumSet.of(Scope.JAVA_FILE)));

//返回我们所有感兴趣的类,即返回的类都被会检查

@Nullable

@Override

public List<Class<? extends UElement>> getApplicableUastTypes() {

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

}

//重写该方法,创建自己的处理器

@Nullable

@Override

public UElementHandler createUastHandler(@NotNull final JavaContext context) {

return new UElementHandler() {

@Override

public void visitClass(@NotNull UClass node) {

node.accept(new NamingConventionVisitor(context, node));

}

};

}

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

public static class NamingConventionVisitor extends AbstractUastVisitor {

JavaContext context;

UClass uClass;

public NamingConventionVisitor(JavaContext context, UClass uClass) {

this.context = context;

this.uClass = uClass;

}

@Override

public boolean visitClass(@org.jetbrains.annotations.NotNull UClass node) {

//获取当前类名

char beginChar = node.getName().charAt(0);

int code = 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则不触碰

return true;

}

return super.visitClass(node);

}

@Override

public boolean visitMethod(@NotNull UMethod node) {

//当前方法不是构造方法

if (!node.isConstructor()) {

char beginChar = node.getName().charAt(0);

int code = beginChar;

//当前方法首字母是大写字母,则报Issue

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

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

“the method must start with lowercase:” + node.getName());

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

return true;

}

}

return super.visitMethod(node);

}

}

}

上文NamingConventionDetector类,已经是全部代码,只检查类名和方法名是否符合驼峰命名法,可以根据具体需求,重写抽象类AbstractUastVisitor的visitXXX方法。

如果处理特定的方法或者其他,也可以使用默认的处理器。重写Scanner相关方法。例如:

@Overridepublic List getApplicableMethodNames() {    return Arrays.asList(“e”,“v”);}

表示e(),v()方法会被检测到,并调用visitMethod()方法,实现自己的逻辑。

@Override    public void visitMethod JavaContext context,  JavaElementVisitor visitor,  PsiMethodCallExpression call, PsiMethod method) {        //todo something        super.visitMethod(context, visitor, call, method);    }

接下来就是注册自定义的Issue:

public class Register extends IssueRegistry {

@NotNull

@Override

public List getIssues() {

return Arrays.asList(NamingConventionDetector.ISSUE);

}

}

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

apply plugin: ‘java-library’

dependencies {

implementation fileTree(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 lib: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。

apply plugin: ‘java-library’

dependencies {

implementation fileTree(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 {    …    lintPublish project(‘: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

复制代码此时Android Studio在右边会打开如下窗口:

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

lintLibrary->build->outputs->aar

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。

一起互勉~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

dXBsb2FkX2ltYWdlcy8xNTY3OTEwOC01Njc1NzM0YzI1MmEyNDEx)

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

lintLibrary->build->outputs->aar

最后

最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。

还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。

[外链图片转存中…(img-PiFYZmrS-1715794530205)]

[外链图片转存中…(img-oZhTBsa2-1715794530206)]

一起互勉~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值