提高代码质量-工具篇


在这片文章中,我将从工具使用的角度上讲述如何提高 Android 代码质量,这些自动化工具包括 Checksytle、Findbugs、PMD 和 Android Lint. 团队中代码意识不一致,水平参差不齐,代码风格迥异,定下的规范也是熟视无睹。这时候就需要借助工具的力量,利用工具自动地帮助我们检测代码,避免代码恶习,预防蚁穴坏堤。

0.1 Fork 这个例子工程

我强烈建议你fork这个例子工程,所有的使用事列都会在这个demo中呈现,同时你可以测试你自己写的规则。

0.2 关于 Gradle 的 Task

理解 Gradle 的 Task 是理解这篇文章的基础,我强烈建议你多看看关于Gradle Task的文章(例如这篇还有这篇),当然,本文也是满满的例子,所以你很容易理解,这也是我建议你 fork 我的代码仓库的原因,把工程导入你的 Android studio,然后你将看到熟悉的 Gradle Task 脚本。如果你还是不太理解,也不用担心,我将最大努力的写好注释。

0.3 关于 这个 demo 的层级结构

Gradle 脚本可以分散在不同的文件中,我在工程中写了三个 gradle 文件:

1 Checkstyle


Check style 是一个帮助开发者维持编码规范标准的一个工具,它能自动地检测 Java 代码,以减少人工检测代码的成本。当你启用 Checkstyle,它能解析你的代码并能告诉你代码中的错误或者不符合定义的规范的地方。

1.1 Android Studio 插件

Checkstyle 提供了多种IDE的插件支持,Android Studio 也不例外。
进入Android Studio设置页面,在插件栏输入Checkstyle:


Checkstyle插件

如果你还没安装 Checkstyle 的插件,进入下载页下载,然后重启 Android Studio。启动 Android studio 后进入 Checkstyle 的设置页面:


Checkstyle设置

在这里我们可以设置 Checkstyle 插件扫描范围,配置文件等信息,默认使用的配置文件是官方提供的文件:sun_checks.xml,我们也可以根据自己项目的需要定义自己的配置文件,配置规则可以参考官方文档
设置完成之后点击 “Apply” 或者 “ok” 按钮,回到代码中,我们便可以看到 Checkstyle 给我们的提示:


Checksylte高亮提示

1.2 Gradle 方式使用Checkstyle

如果我们需要把 Checkstyle 继承到自动编译服务器中,例如:jenkins,我们需要利用 Gradle Task来执行 Checkstyle,下面这段脚本展示了在 Gradle task 的 Checkstyle 的基本配置:

<code class="bash">task checkstyle(<span class="hljs-built_in" style="color: rgb(102, 0, 102);">type</span>: Checkstyle) {
    configFile file(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/config/quality/checkstyle/checkstyle.xml"</span>) // Where my    checkstyle config is...
    configProperties.checkstyleSuppressionsPath = file(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/config/quality/checkstyle/suppressions.xml"</span>).absolutePath // Where is my suppressions file <span class="hljs-keyword" style="color: rgb(0, 0, 136);">for</span> checkstyle is...
    <span class="hljs-built_in" style="color: rgb(102, 0, 102);">source</span> <span class="hljs-string" style="color: rgb(0, 136, 0);">'src'</span>
    include <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/*.java'</span>
    exclude <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/gen/**'</span>
    classpath = files()
}</code>

这个 task 将会根据你指定的 checkstyle.xml 和 suppressions.xml 文件来分析你的代码。你可以在 Android Studio 中执行这个任务:


执行完成之后,checkstyle 工具将会把每一个不合法的问题显示在控制台中。

2 FindBugs


FindBugs 这个名字本身已经揭示了它的作用,“FindBugs uses static analysis to inspect Java bytecode for occurrences of bug patterns.” FindBugs 是一个工具,它能通过静态分析方式扫描 Java 字节码,发现其中的可能出现 bug 的代码,它能发现一些常规的低级的错误,例如一些错误的逻辑操作,也能发现一些比较隐晦的错误。
例如:

<code class="cs">   Person person = (Person) map.<span class="hljs-keyword" style="color: rgb(0, 0, 136);">get</span>(<span class="hljs-string" style="color: rgb(0, 136, 0);">"bob"</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136);">if</span> (person != <span class="hljs-keyword" style="color: rgb(0, 0, 136);">null</span>) {
        person.updateAccessTime();
    }
    String name = person.getName();</code>

最后一行代码,可能会出现空指针错误。
又如:

<code class="objectivec">    b<span class="hljs-variable" style="color: rgb(102, 0, 102);">.replace</span>(<span class="hljs-string" style="color: rgb(0, 136, 0);">'b'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0);">'p'</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136);">if</span>(b<span class="hljs-variable" style="color: rgb(102, 0, 102);">.equals</span>(<span class="hljs-string" style="color: rgb(0, 136, 0);">"pop"</span>)) {
        Log<span class="hljs-variable" style="color: rgb(102, 0, 102);">.d</span>(<span class="hljs-string" style="color: rgb(0, 136, 0);">""</span>,<span class="hljs-string" style="color: rgb(0, 136, 0);">""</span>);
    }</code>

b.replace('b', ‘p’);这段代码对b不会产生影响,所以是无效的。

2.1 Android Studio 插件

同样,FIndbugs 也提供了 Android Studio 的插件支持,插件的获取过程和 Checkstyle 一样,在安装后之后重启 Android studio。值得注意的是 Findbugs 分析的是 Java 字节码,所以在启用 Findbugs 之前要保证你的工程是编译过的,在 FIndbugs 扫描之后,如果发现问题,会在对应的代码出给出提示:


findbugs提示

2.2 Gradle 脚本使用

在Gradle使用非常简单,下面的脚本展示了如何 FindBugs:

<code class="bash">task findbugs(<span class="hljs-built_in" style="color: rgb(102, 0, 102);">type</span>: FindBugs) {
    ignoreFailures = <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
    effort = <span class="hljs-string" style="color: rgb(0, 136, 0);">"max"</span>
    reportLevel = <span class="hljs-string" style="color: rgb(0, 136, 0);">"high"</span>
    excludeFilter = new File(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/config/quality/findbugs/findbugs-filter.xml"</span>)
    classes = files(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/app/build/classes"</span>)
    <span class="hljs-built_in" style="color: rgb(102, 0, 102);">source</span> <span class="hljs-string" style="color: rgb(0, 136, 0);">'src'</span>
    include <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/*.java'</span>
   exclude <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/gen/**'</span>

    reports {
       xml.enabled = <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
        html.enabled = <span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>
        xml {
       destination <span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">$project</span>.buildDir/reports/findbugs/findbugs.xml"</span>
   }
    html {
        destination <span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">$project</span>.buildDir/reports/findbugs/findbugs.html"</span>
    }
}

    classpath = files()
}</code>

脚本任务和 Checkstyle 类似,FindBugs 可以根据我们指定的范围进行扫描,这个范围我们可以通过一个过滤规则文件来制定扫描结果报告支持 HTML 和 XML 两种格式。excludeFilter 指定了过滤器配置文件,reports 指定了检测报告的文件格式和文件地址。执行 Findbugs 的 task 非常简单,和 Checkstyle 一样。

2.3 Findbugs 使用技巧

我强烈建议为 Findbugs 配置一个过滤文件,因为 Android 工程和 Java 工程稍微有些不一样,Android 工程自动生成的 R 文件并不符合 Findbugs 的规范,需要过滤掉。另外要注意的是:Findbugs 分析的是字节码,你需要先编译,再进行 Findbugs 的分析。

3 PMD


这个工具比较有趣:其实 PMD 真正的名字并不是 PMD 。 在其官方网站上你会发现两个非常有趣的名字:

  • Pretty Much Done
  • Project Meets Deadline

事实上 PMD 是一个非常强大的工具,它的作用类似 Findbugs,但是它的检测扫描是基于源码的,而且 PMD 不仅仅能检测 Java 语言,还能检测其他语言。PMD 的目标和 Findbugsd 非常的相似,都是通过定义的规则静态分析代码中可能出现的错误,为什么要同时使用 PMD 和 Findbugs呢?由于 Findbugs 和 PMD 的扫描方式不一样,PMD 能发现的一些 Findbugs 发现不了的问题,反之亦然。

3.1 Android 插件中使用

插件的下载过程不再赘述,安装完成重启之后,到顶部菜单 Tools 栏目可以找到 QAplug 选项,可以执行代码分析:


PMD代码分析

执行完成,会在控制台输出结果:


PMD执行结果

3.2 在 Gradle 脚本中使用

下面的脚本代码展示了如何使用PMD:

<code class="bash">task pmd(<span class="hljs-built_in" style="color: rgb(102, 0, 102);">type</span>: Pmd) {
    ruleSetFiles = files(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/config/quality/pmd/pmd-ruleset.xml"</span>)
    ignoreFailures = <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
    ruleSets = []

   <span class="hljs-built_in" style="color: rgb(102, 0, 102);">source</span> <span class="hljs-string" style="color: rgb(0, 136, 0);">'src'</span>
   include <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/*.java'</span>
   exclude <span class="hljs-string" style="color: rgb(0, 136, 0);">'**/gen/**'</span>

    reports {
        xml.enabled = <span class="hljs-literal" style="color: rgb(0, 102, 102);">false</span>
        html.enabled = <span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>
    xml {
        destination <span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">$project</span>.buildDir/reports/pmd/pmd.xml"</span>
    }
   html {
        destination <span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">$project</span>.buildDir/reports/pmd/pmd.html"</span>
       }
    }
}</code>

配置都和 Findbus 如出一辙,PMD 同样也可以输出 HTML 和 XML 报告,例子中选中的是 HTML 格式。我强烈建议你定义自己的 rulesets 文件(规则集合),关于 rulesets的配置,可以参考官方文档,PMD存在争议的规则比 Findbugs 要多,例如对于嵌套的 “if statement” 它总是提醒你 “These nested if statements could be combined”,或者对空的 “if statement ” 总是提醒你 “Avoid empty if statements”,不过,我觉得是否需要把嵌套 “if statement” 合并到一个 “if statement” 取决于你或者你的团队自己来定义,我不太建议合并 “if statement ” 这样会降低代码可读性。执行 PMD 的 task 非常简单,和 Checkstyle 一样。

4 Android Lint

“The Android lint tool is a static code analysis tool that checks your Android project source files for potential bugs and optimization improvements for correctness, security, performance, usability, accessibility, and internationalization.” 正如官网所说,Android Lint 是另一个静态代码分析工具,专门针对 Android 工程。Android Lint 除了对代码扫描,分析潜在问题之外,还能对Android的资源进行检测,无用的资源,错位的dip资源等。

4.1 Gradle 脚本使用

<code class="bash">android {
    lintOptions {
    abortOnError <span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>
     lintConfig file(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">${project.rootDir}</span>/config/quality/lint/lint.xml"</span>)
    // <span class="hljs-keyword" style="color: rgb(0, 0, 136);">if</span> <span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>, generate an HTML report (with issue explanations, sourcecode, etc)
    htmlReport <span class="hljs-literal" style="color: rgb(0, 102, 102);">true</span>
    // optional path to report (default will be lint-results.html <span class="hljs-keyword" style="color: rgb(0, 0, 136);">in</span> the builddir)
    htmlOutput file(<span class="hljs-string" style="color: rgb(0, 136, 0);">"<span class="hljs-variable" style="color: rgb(102, 0, 102);">$project</span>.buildDir/reports/lint/lint.html"</span>)
}</code>

我建议你单独指定一个配置文件来决定是否过滤一些规则,规则的定义可以参考最新ADT给出的规则,参考这里。使用 “severity” 配置为 “ignore” 来过滤指定的规则。 执行 Lint 和执行 Checkstyle 的 task 一样。执行完成之后到结果输出目录中查看报告,例如下面是我(译者)执行自己的工程输出的部分截图:


5 在一个任务统一使用以上工具

以上介绍完了四个工具,现在我们来看看如何一次同时运行四个工具?我们可以管理 gradle task 之间的依赖关系,使得我们在执行一个 task 任务的同时其他 task 也能被执行。使用 Gradle 提供的方法,我们可以把四个工具的执行任务添加为 “check” task 的依赖:

<code class="sql"><span class="hljs-operator"><span class="hljs-keyword" style="color: rgb(0, 0, 136);">check</span>.dependsOn <span class="hljs-string" style="color: rgb(0, 136, 0);">'checkstyle'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0);">'findbugs'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0);">'pmd'</span>, <span class="hljs-string" style="color: rgb(0, 136, 0);">'lint'</span></span></code>

现在,只要我们只想 “check” 这个 task ,Checkstyle、Windbags、PMD 和 Android Lint 都会自动执行。在 commit/push/merge request 之前 执行一下 check 任务,对我们代码质量的提高将是一种非常棒的方式。执行这个任务比较简单,你可以在命令行中执行:

<code class="sql">    gradlew <span class="hljs-operator"><span class="hljs-keyword" style="color: rgb(0, 0, 136);">check</span></span></code>

6 总结

正如上文所说,在 Gradle 中使用这些工具是非常简单的。这些工具不仅能在本地使用,还能部署到我们的自动化编译服务器上,比如 Jenkins/Hudson,自动处理扫描我们的代码并输出报告。

转自:http://blog.csdn.net/dj0379/article/details/51959134
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于preevision的autosar adaptive设计-上 autosar adaptive是一种汽车电子系统的架构和开发标准,旨在满足汽车行业对日益增长的功能和复杂性的需求。而基于preevision的autosar adaptive设计是一种通过使用preevision工具进行autosar adaptive系统设计和开发的方法。 preevision是一种功能强大的工程工具,专门用于汽车电子系统的设计和开发。它提供了一套丰富的工具和功能,可帮助工程师轻松地创建、模拟和验证autosar adaptive系统的设计。 基于preevision的autosar adaptive设计包括以下关键步骤: 首先,工程师需要使用preevision工具创建autosar adaptive系统的模型。这可以通过使用preevision的图形界面来完成,工程师可以在其中定义autosar adaptive系统的各个组件,包括应用程序、服务、接口和通信。 接下来,工程师需要使用preevision工具进行模型的验证和仿真。通过使用preevision的仿真功能,工程师可以模拟autosar adaptive系统的行为和性能,以确保系统的设计满足要求。 一旦模型被验证和仿真成功,工程师就可以使用preevision工具生成与autosar adaptive系统相关的代码和文档。preevision提供了自动代码生成的功能,可以根据系统模型生成各个组件的代码,包括应用程序、服务和接口。 最后,工程师可以使用preevision工具进行系统的集成和部署。preevision提供了一套完整的工具和功能,可以帮助工程师将autosar adaptive系统部署到实际的汽车电子控制单元(ECU)上,并与其他系统进行集成。 基于preevision的autosar adaptive设计具有许多优点。首先,它可以帮助工程师快速而准确地设计和开发autosar adaptive系统,提高开发效率。其次,preevision提供了一套丰富的工具和功能,使工程师能够对系统进行全面的验证和仿真,从而确保系统的质量和性能。最后,基于preevision的autosar adaptive设计能够帮助企业实现系统的自动化开发和部署,减少人力成本和时间成本。 综上所述,基于preevision的autosar adaptive设计是一种高效、准确和可靠的方法,可以帮助汽车行业设计和开发符合autosar adaptive标准的系统。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值