android Findbugs使用

1.前言:

一个免费的 Android Studio插件,可以在开发早期检测出常见的 Java bug."我们通常都会在APP 上线之后,发现各种错误,尤其是空指针异常,这些错误对于用户体验来说是非常不好的,但其实大部分的问题,我们都能够提前发现。在编写代码的过程中,可能不会时时刻刻记得检查空的引用,还有删除没有用过的变量,在我们自己检测的过程中可能难以发现问题,一旦app上线,用户的时候用环境改变,这些潜在的问题就可能会冒出来”

2.FindBugs

顾名思义,FindBugs是一个寻找bug的工具,更具体的说FindBugs是一个静态检测java代码的工具,检测完成之后会生成一份详细的报告,借助这份报告可以找到潜在的Bug,比如前面说到的NullPointException,还可以检查特定的资源没有关闭,例如:查询数据库没有调用Cursor.close()等。

FindBugs官网地址:http://findbugs.sourceforge.net/

2.1作用

检测范围 :

常见代码错误,序列化错误

可能导致错误的代码,如空指针引用

国际化相关问题:如错误的字符串转换

可能受到的恶意攻击,如访问权限修饰符的定义等

多线程的正确性:如多线程编程时常见的同步,线程调度问题。

运行时性能问题:如由变量定义,方法调用导致的代码低效问题

2.2Android Studio gradle配置

在setting->plugin里边安装成功之后重启AS:

2-2-1

安装成功以后:会在logCat同级出现一个findBugs的图标,点击之后会有如下界面:

2-2-2

圈1.是点击执行的按钮;

圈2.是检测发现的问题目录,中间是错误目录或者错误所对应的类;

● Bad practice 坏的实践 

一些不好的实践,下面列举几个: HE: 类定义了equals,却没有hashCode;或类定义了equals,却使用Object.hashCode;或类定义了hashCode,却没有equals;或类定义了hashCode,却使用Object.equals;类继承了equals,却使用Object.hashCode。 SQL:Statement 的execute方法调用了非常量的字符串;或Prepared Statement是由一个非常量的字符串产生。 DE: 方法终止或不处理异常,一般情况下,异常应该被处理或报告,或被方法抛出。 Malicious code vulnerability 可能受到的恶意攻击 

如果代码公开,可能受到恶意攻击的代码,下面列举几个: FI: 一个类的finalize应该是protected,而不是public的。 MS:属性是可变的数组;属性是可变的Hashtable;属性应该是package protected的。 

● Correctness 一般的正确性问题 

可能导致错误的代码,下面列举几个: 

NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否null;null值产生并被引用; 

null值产生并在方法的异常路径被引用; 

传给方法一个声明为@NonNull的null参数; 

方法的返回值声明为@NonNull实际是null。 

Nm: 类定义了hashcode方法,但实际上并未覆盖父类Object的hashCode;类定义了tostring方法,但实际上并未覆盖父类Object的toString;很明显的方法和构造器混淆;方法名容易混淆。 

SQL:方法尝试访问一个Prepared Statement的0索引;方法尝试访问一个ResultSet的0索引。 

UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。 

● Dodgy 危险的 

具有潜在危险的代码,可能运行期产生错误,下面列举几个: 

CI: 类声明为final但声明了protected的属性。 

DLS:对一个本地变量赋值,但却没有读取该本地变量;本地变量赋值成null,却没有读取该本地变量。 

ICAST: 整型数字相乘结果转化为长整型数字,应该将整型先转化为长整型数字再相乘。 

INT:没必要的整型数字比较,如X <= Integer.MAX_VALUE。 NP: 对readline的直接引用,而没有判断是否null;对方法调用的直接引用,而方法可能返回null。 REC:直接捕获Exception,而实际上可能是RuntimeException。 ST: 从实例方法里直接修改类变量,即static属性。 

https://blog.csdn.net/natural_story/article/details/53260211这是关于findBugs的详细规则

● Performance 性能问题 

可能导致性能不佳的代码,下面列举几个: 

DM:方法调用了低效的Boolean的构造器,而应该用Boolean.valueOf(…); 

用类似Integer.toString(1) 代替new Integer(1).toString; 

方法调用了低效的float的构造器,应该用静态的valueOf方法。 

SIC:如果一个内部类想在更广泛的地方被引用,它应该声明为static。 

SS: 如果一个实例属性不被读取,考虑声明为static。 

UrF:如果一个属性从没有被read,考虑从类中去掉。 

UuF:如果一个属性从没有被使用,考虑从类中去掉。 

● Multithreaded correctness 多线程的正确性多线程编程时,可能导致错误的代码,下面列举几个: 

ESync:空的同步块,很难被正确使用。 

MWN:错误使用notify,可能导致IllegalMonitorStateException异常;或错误的使用wait。 

No: 使用notify而不是notifyAll,只是唤醒一个线程而不是所有等待的线程。 

SC: 构造器调用了Thread.start,当该类被继承可能会导致错误。 

● Internationalization 国际化 当对字符串使用upper或lowercase方法,如果是国际的字符串,可能会不恰当的转换

圈3.是错误的提示;

2.3FindBugs配置:

2.3.1在设置里找到FB的配置处有一些默认的配置

2-3-1

2.3.2配置规则(Gradle插件):

这里建议大家单独用gradle去设置检查规则

2-3-1

在app的build.gradle里添加一下方法

2-3-2

task findbugs(type: FindBugs,dependsOn:"assembleDebug") {

ignoreFailures =false

    effort ="max"

    reportLevel ="high"

    excludeFilter =new File("${project.rootDir}/check_config/findbugs.xml")//这里是配置的校验文件目录;

    classes = files("${project.rootDir}/app/build/intermediates/classes")

    source'src'

    include'**/*.java'

    exclude'**/gen/**'

    reports {

xml.enabled =false

        html.enabled =true

        xml { 

                destination"$reportsDir/findbugs/findbugs.xml"  //这里是报告产生的路径

        }

        html {

                destination"$reportsDir/findbugs/findbugs.html"  //这里是报告产生的路径

        }

}

classpath = files()

}

代码解释:

引入FindBugs的插件:apply plugin: "findbugs"。

定义一个task任务,这个任务的类型是FindBugs,指定依赖assembleDebug是为了先生成.classe文件,才能对代码进行静态分析。

ignoreFailures:有警告错误的时候也是允许构建。

reportLevel:报告的级别,默认是medium ,Low,Medium,High一般来说我们首先关注的是高级别的报告,再关注低一级别的报告。

classes和source分别是对应的.classe文件夹地址,和源代码文件地址。

repoets指定报告类型,有两种方式xml和html,只允许一种输出格式。

effort 可以设置成max和min,一般在内存和时间不紧张的情况下都用max

定义完成之后,同步下Gradle,之后在右侧的Gradle的菜单中找到对于的Module,就可以在Tasks中找到对应的findBugs任务,点击即可运行。

2.4 findbugs-filter

excludeFilter就是用来配置过滤器的,过滤内容则通过findbugs-filter.xml文件来约定,也是findbugs配置中最重要的一个环节。

findbugs的检查报告包括了分好几大类型的警告(Warning Type),如图中的Bad prictice Warnings,Internationalization Warnings等类型,每个类型下又有其他的代码警告(Code Warning),如图中 的code码Nm和后面的介绍,当然其中有很多我们不关心的警告Code,比如Eq(建议用equals()来代替==进行比较的警告)UrF(提示Activity中的控件如TextView没有初始化,其实我们是通过注入初始化的)等在某些类型的警告中是我们不关注的,需要过滤掉。接下来简单说一下如何配置过滤规则。

2-4-1

过滤标签介绍

<Bug>设置警告的类型

<Confidence>设置过滤等级

<Package>设置过滤包名

<Class>设置过滤的类名

<Source>设置过滤的源文件名

<Method>设置过滤的方法名

过滤组合操作符:

<Or>或

<And>与

<Not>非

过滤器设置示例

这里把国际化相关的警告全部过滤掉了

<Match>

    <Bug code = "IJU"/>

</Match>

有的时候我们可能只想过滤掉某个大的类别中的几个小的类型的警告,比如过滤掉Performence中的UrF

<Match>

    <And>

    <Bug category="PERFORMANCE"/>

    <Bug code= "SIC,UrF,UuF"/>

    </And>

</Match>

过滤某个特定的类:

<Match>

<Class name = "com.foobar.MyClass"/>

</Match>

运用组合条件过滤某个类中的特定内容警告:

<Match>

<Class name = "com.foobar.MyClass"/>

<Or>

<Method name = "frob" category="int,java.lang.String" returns = "void">

</Method>

<Method name = "blat" category=" " returns = "boolean"/>

</Or>

</Match>

当然用法可以很灵活,能够非常方便的定制符合业务需求的过滤器 ,从而达到最高效解决我们关注问题的目的。


2.5FindBugs报告

在 logcat同级的操作中可以指定目录,在gradle project中点击findbugs执行会在

build\reports\findbugs\下边生成报告,报告的格式根据上文提到的app.gradle配置决定

单个文件执行结果:

2-5-1

生成报告如下:

2-5-2



小记:

这个插件是基于Java的结果,现在android如果使用kotlin语言,那么就要考虑使用性。后期会为大家分享基于kotlin的一些检测工具

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,833评论 25 707
  • 冬去春来,植物都慢慢的恢复了生机,月季的枝条由青绿变为绿油油的,长出了娇嫩的叶子,小红果挂在枝条间像一个个小灯...
    韩小月_cfc4阅读 155评论 0 0
  • 一位95年出生的大学生,正在准备考研。 在这忙碌复习备考之际,她找到了我,要做九数生命能量解读,主因是她当下不开心...
    莞尔的人生阅读 1,239评论 2 8