java 自定义警告_android – 编写自定义lint警告以检查自定义注释

我写了以下注释:

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Retention(RetentionPolicy.SOURCE)

@Target({ElementType.METHOD})

public @interface Warning {

}

这是为了注释那些在不小心调用时可能导致问题的方法.我在我的项目中添加了一个注释处理器,但这只在javac命令的日志输出中提供了警告.我希望此警告与其他lint警告一起出现在Android Studio中,并且调用带有此批注的方法.这就是我尝试编写自定义lint规则的原因.我有lint规则的基本框架:

import com.android.tools.lint.detector.api.Category;

import com.android.tools.lint.detector.api.Detector;

import com.android.tools.lint.detector.api.Implementation;

import com.android.tools.lint.detector.api.Issue;

import com.android.tools.lint.detector.api.Scope;

import com.android.tools.lint.detector.api.Severity;

public class CaimitoDetector extends Detector implements Detector.JavaScanner {

public static final Issue ISSUE = Issue.create(

"WarningAnnotation",

"This method has been annotated with @Warning",

"This method has special conditions surrounding it's use, be careful when using it and refer to its documentation.",

Category.USABILITY, 7, Severity.WARNING,

new Implementation(CaimitoDetector.class, Scope.JAVA_FILE_SCOPE));

@Override

public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {

}

}

import com.android.tools.lint.client.api.IssueRegistry;

import com.android.tools.lint.detector.api.Issue;

import java.util.Collections;

import java.util.List;

public class CaimitoIssueRegistry extends IssueRegistry {

@Override

public List getIssues() {

return Collections.singletonList(CaimitoDetector.ISSUE);

}

}

但我不知道如何从这里开始.如何检查方法上是否存在annoation,并发出警告,使其在Android Studio中可见?

UPDATE

这是我的Detector类,适合任何想要做同样事情的人:

import com.android.annotations.NonNull;

import com.android.tools.lint.client.api.JavaParser.ResolvedAnnotation;

import com.android.tools.lint.client.api.JavaParser.ResolvedMethod;

import com.android.tools.lint.client.api.JavaParser.ResolvedNode;

import com.android.tools.lint.detector.api.Category;

import com.android.tools.lint.detector.api.Context;

import com.android.tools.lint.detector.api.Detector;

import com.android.tools.lint.detector.api.Implementation;

import com.android.tools.lint.detector.api.Issue;

import com.android.tools.lint.detector.api.JavaContext;

import com.android.tools.lint.detector.api.Scope;

import com.android.tools.lint.detector.api.Severity;

import com.android.tools.lint.detector.api.Speed;

import java.io.File;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import lombok.ast.AstVisitor;

import lombok.ast.ConstructorInvocation;

import lombok.ast.ForwardingAstVisitor;

import lombok.ast.MethodInvocation;

import lombok.ast.Node;

public class CaimitoAnnotationDetector extends Detector implements Detector.JavaScanner {

private static final String WARNING_ANNOTATION = "com.treemetrics.caimito.annotations.Warning";

public static final Issue ISSUE = Issue.create(

"Waqrning.",

"Be careful when using this method.",

"This method has special conditions surrounding it's use," +

" be careful when calling it and refer to its documentation.",

Category.USABILITY,

7,

Severity.WARNING,

new Implementation(

CaimitoAnnotationDetector.class,

Scope.JAVA_FILE_SCOPE));

@Override

public boolean appliesTo(@NonNull Context context, @NonNull File file) {

return true;

}

@NonNull

@Override

public Speed getSpeed() {

return Speed.FAST;

}

private static void checkMethodAnnotation(@NonNull JavaContext context,

@NonNull ResolvedMethod method,

@NonNull Node node,

@NonNull ResolvedAnnotation annotation) {

String signature = annotation.getSignature();

if(WARNING_ANNOTATION.equals(signature) || signature.endsWith(".Warning")) {

checkWarning(context, node, annotation);

}

}

private static void checkWarning(@NonNull JavaContext context,

@NonNull Node node,

@NonNull ResolvedAnnotation annotation) {

context.report(ISSUE, node, context.getLocation(node), "Warning");

}

// ---- Implements JavaScanner ----

@Override

public List> getApplicableNodeTypes() {

return Arrays.asList(

MethodInvocation.class,

ConstructorInvocation.class);

}

@Override

public AstVisitor createJavaVisitor(@NonNull JavaContext context) {

return new CallChecker(context);

}

private static class CallChecker extends ForwardingAstVisitor {

private final JavaContext mContext;

public CallChecker(JavaContext context) {

mContext = context;

}

@Override

public boolean visitMethodInvocation(@NonNull MethodInvocation call) {

ResolvedNode resolved = mContext.resolve(call);

if(resolved instanceof ResolvedMethod) {

ResolvedMethod method = (ResolvedMethod) resolved;

checkCall(call, method);

}

return false;

}

@Override

public boolean visitConstructorInvocation(@NonNull ConstructorInvocation call) {

ResolvedNode resolved = mContext.resolve(call);

if(resolved instanceof ResolvedMethod) {

ResolvedMethod method = (ResolvedMethod) resolved;

checkCall(call, method);

}

return false;

}

private void checkCall(@NonNull Node call, ResolvedMethod method) {

Iterable annotations = method.getAnnotations();

annotations = filterRelevantAnnotations(annotations);

for(ResolvedAnnotation annotation : annotations) {

checkMethodAnnotation(mContext, method, call, annotation);

}

}

private Iterable filterRelevantAnnotations(Iterable resolvedAnnotationsIn) {

List resolvedAnnotationsOut = new ArrayList<>();

for(ResolvedAnnotation resolvedAnnotation : resolvedAnnotationsIn) {

if(resolvedAnnotation.matches(WARNING_ANNOTATION)) {

resolvedAnnotationsOut.add(resolvedAnnotation);

}

}

return resolvedAnnotationsOut;

}

}

}

更新2

您可以通过在项目的根目录中创建lint.xml文件并在其中添加自定义lint规则来将自定义lint检查与Android Studio检查集成,如下所示:

请注意,问题标记的id是CaimitoDetector类中Issue.create()方法的第一个参数提供的id.您还必须将通过构建lint规则输出的jar文件复制到/home/{user}/.android/lint文件夹中以使其正常工作.我为此写了一个自定义gradle任务.这是我的lint规则的build.gradle文件

apply plugin: 'java'

targetCompatibility = '1.7'

sourceCompatibility = '1.7'

repositories {

jcenter()

}

dependencies {

compile 'com.android.tools.lint:lint-api:24.2.1'

compile 'com.android.tools.lint:lint-checks:24.2.1'

}

jar {

manifest {

attributes 'Manifest-Version': 1.0

attributes 'Lint-Registry': 'com.treemetrics.caimito.lint.CaimitoIssueRegistry'

}

}

defaultTasks 'assemble'

task copyLintJar(type: Copy) {

description = 'Copies the caimito-lint jar file into the {user.home}/.android/lint folder.'

from('build/libs/')

into(System.getProperty("user.home") + '/.android/lint')

include("*.jar")

}

// Runs the copyLintJar task after build has completed.

build.finalizedBy(copyLintJar)

更新3

您还可以将Java lint项目添加为对其他项目的依赖项,以获得与更新2相同的效果.

78ZsE.png

更新4

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值