代码优化--Android Lint(二)

Android lint是在ADT16(Android SDK Tools 16 )提供的新工具,它是一个代码扫描工具,用于检测 Android 的代码质量。developers介绍

简单介绍
Lint 会根据预先配置的检测标准检查我们 Android 项目的源文件,发现潜在的 bug 或者可以优化的地方,优化的内容主要包括以下几方面:

  • Correctness: 不够完美的编码,比如硬编码、使用过时 API 等 ;
  • Performanc: 对性能有影响的编码,比如:静态引用,循环引用等 ;
  • Internationalization: 国际化,直接使用汉字,没有使用资源引用等 ;
  • Security: 不安全的编码,比如在 WebView 中允许使用 JavaScript Interface 等 ;
  • Usability: 可用的,有更好的替换的,比如排版、图标格式建议.png格式 等 ;
  • Accessibility: 辅助选项,比如 ImageView 的 contentDescription 往往建议在属性中定义等;

Lint 检测代码的过程如下图所示:

  • App 源文件:包括 Java 代码,XML 代码,图标,以及 ProGuard 配置文件等。
  • lint.xml:Lint 检测的执行标准配置文件,可以修改它来允许/禁止报告一些问题。

Android Studio直接使用Lint检查项目

Android Studio 2.0 以后,谷歌将 Lint 检查整合到了 IDE 之中,提供了方便的图形界面操作,检测结果也会在底部 Inspection Results 中展现。

Lint规则配置
在开始之前,可以通过对 lint.xm / lintOptions 的配置去实现符合自己项目的 Lint 检测规则。

lintOptions: 定义在 gradle(build.gradl) 文件中,下面列举 lintOptions 可定义的选项。

android {
    lintOptions {
        // true--关闭lint报告的分析进度
        quiet true
        // true--错误发生后停止gradle构建
        abortOnError false
        // true--只报告error
        ignoreWarnings true
        // true--忽略有错误的文件的全/绝对路径(默认是true)
        //absolutePaths true
        // true--检查所有问题点,包含其他默认关闭项
        checkAllWarnings true
        // true--所有warning当做error
        warningsAsErrors true
        // 关闭指定问题检查
        disable 'TypographyFractions', 'TypographyQuotes'
        // 打开指定问题检查
        enable 'RtlHardcoded', 'RtlCompat', 'RtlEnabled'
        // 仅检查指定问题
        check 'NewApi', 'InlinedApi'
        // true--error输出文件不包含源码行号
        noLines true
        // true--显示错误的所有发生位置,不截取
        showAll true
        // 回退lint设置(默认规则)
        lintConfig file("default-lint.xml")
        // true--生成txt格式报告(默认false)
        textReport true
        // 重定向输出;可以是文件或'stdout'
        textOutput 'stdout'
        // true--生成XML格式报告
        xmlReport false
        // 指定xml报告文档(默认lint-results.xml)
        xmlOutput file("lint-report.xml")
        // true--生成HTML报告(带问题解释,源码位置,等)
        htmlReport true
        // html报告可选路径(构建器默认是lint-results.html )
        htmlOutput file("lint-report.html")
        //  true--所有正式版构建执行规则生成崩溃的lint检查,如果有崩溃问题将停止构建
        checkReleaseBuilds true
        // 在发布版本编译时检查(即使不包含lint目标),指定问题的规则生成崩溃
        fatal 'NewApi', 'InlineApi'
        // 指定问题的规则生成错误
        error 'Wakelock', 'TextViewEdits'
        // 指定问题的规则生成警告
        warning 'ResourceAsColor'
        // 忽略指定问题的规则(同关闭检查)
        ignore 'TypographyQuotes'
    }
}

lint.xml:用来指定你想禁用哪些lint检查功能,以及自定义问题严重度 (problem severity levels),此时可以通过 lintOptions 中的 lintConfig file("lint.xml") 来指定配置文件的所在目录。

Lint.xml 中关键是对 issue(用id指定)的 severity 进行指定,lint.xml文件由一个封闭的父标签组成,它包含了一个或者多个子标签。Lint为每一个定义了唯一的id属性值,通过设置标识的安全属性,你可以改变一个问题的安全级别,或者这个问题的 lint检查,并且可以指定该 issue作用于指定的文件还是当前项目。
把 lint.xml放在项目的根目录中,命令行执行 lint时候,lint就会用lint.xml中的规则。另外,执行 lint时还可以用参数 –config 指定一个全局的配置用于所有的项目。当项目中已有 lint.xml,则对于某个 issue而言,在lint.xml中没有对该 issue特别定制的情况下,–config指定的文件中的该 issue的定制才起作用。 整体结构如下:

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- 需要配置的 issues 列表 -->
    <!-- 关闭对应的检测-->
    <issue id="IconMissingDensityFolder" severity="ignore" />

    <!-- 在一些特定的文件中关闭对应的检测 -->
    <issue id="ObsoleteLayoutParam">
        <ignore path="res/layout/activation.xml" />
        <ignore path="res/layout-xlarge/activation.xml" />
    </issue>

    <!-- 将对应的检测级别修改 -->
    <issue id="HardcodedText" severity="error" />
</lint>

id 的获取我们可以通过命令行 lint --list 获取。如果无法直接执行 lint 命令,我们可以在 /.bash_profile 中添加 PATH="~/Library/Android/sdk/tools/bin:${PATH}" 即可。

使用方式

1. 选择要分析的项目或者文件、文件夹,从菜单栏,选择工具栏 - > Analyze -> Inspect Code;

2. 选择检查的范围(整个工程/指定Module/指定文件/文件夹)

  • Project Files:所有项目文件
  • Project Production Files:项目的代码文件
  • Project Test Files:项目的测试文件
  • Open Files:当前打开的文件
  • Module ‘Module Name’:主要的 *** 模块
  • Current File:当前文件

3. 结果展示
左侧会提示你需要修改的地方,点击某一条,右侧则会出现关于该问题的详细描述。

部分检测结果的分析:

4. 结果分析
得到检查的结果后,就得开始对代码进行优化了,但是 Lint 报的某些警告的确是没必要的,这时我们可以选择忽略这些警告。因此其实在分析处理时,我们可以根据实际的需求进行忽略。其中忽略警告可以分两种:

  • Java 代码中
  • XML 文件夹中

在 Java 代码中忽略 Lint 警告
忽略 Lint 警告的注解跟 @SuppressWarnings 很类似,@SuppressLint(“忽略的警告名称”)。下面的代码演示了如何忽略 Lint 对使用 -- 新 API 的警告:

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

要是不清楚要忽略的警告具体是什么名字,可以直接忽略 all,当然是当前类/方法/对象:

@SuppressLint("all")

在 XML代码中忽略 Lint 警告
只需两步:

  1. xml 中声明 tools 命名空间
  2. 使用 tools:ignore=“忽略的警告名”
    如:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              tools:ignore="all"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              android:background="@color/white">

5. 检测无用资源文件
随着不断地进行代码版本迭代,非常容易遗留一些无用的代码/源文件,这时可以通过直接指定检测无用资源,实现 Lint 清除。
方法:工具栏 -> Analyze -> Run Inspection By Name..,输入要检测的内容(此时是unused resources,当然也可以删选其他内容),然后再选择检测范围开始检测。

检测内容

当检测出的无用资源过多时,你会发现一个一个处理时多么的繁琐,这时可以注意到,下图右边有解决方法:Remove All Unused Resources,点击后,就没有了。
注:使用该方法后可能会造成某些资源误删的情况,因此删除之后不要忘记编译运行,利用 git 对其中误删资源进行 reset。

检测结果

对于无用资源的处理方式有:

  • "Remove All Unused Resources ":移出无用资源;
  • "Remove Declaration for XXX ":移出对XXX的声明;
  • "Add a tools:keep attribute to mark as implicitly used ":添加 tools:keep 属性来标记隐式使用,在XML 文件的根元素 resources 里自动添加了 tools 命名空间,再加上"tools:keep" 。
tools:keep
适用于 <resources> 资源标签。当开启了资源压缩(shrinking resource)功能时,这个属性允许你指定哪些资源需要被保留。
因为开启了资源压缩功能后,未被引用的资源文件会在构建过程中被移除,而部分使用 Resources.getIdentifier() 进行引用的资源文件可能被误删。
此时我们可以使用该属性 指定哪些资源需要保留,不能被移除。

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"    
tools:keep="@layout/used_1,@layout/used_2,@layout/*_3" />

可参考:Android开发技巧之xml tools属性详解

参考文章:
阿里的代码规范检测插件
Android 性能优化:使用 Lint 优化代码、去除多余资源
Android Studio使用Lint进行代码检查
如何在android studio 中使用 link工具
Android Studio 的代码检查功能,使用 Lint 工具优化代码(笔记)
Android性能优化之工具篇 — — Android Lint
Inspect Code功能
Lint工具使用实录及整理

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