Android性能优化之工具篇 — — Android Lint

官方介绍原文请移步:http://tools.android.com/tips/lint

Lint简介

Android lint是在ADT16提供的新工具,它是一个代码扫描工具,能够帮助我们识别资源、代码结构存在的问题。

Lint优化哪些问题

  • 遗漏的翻译(没用上的翻译)比如国际化未被翻译的字段值
  • 布局性能(以前是 layoutopt工具,可以解决无用布局、嵌套太多、布局太多)
  • 未使用到资源
  • 不一致的数组大小
  • 国际化问题(硬编码)
  • 图标的问题(重复的图标,错误的大小)
  • 可用性问题(如不指定的文本字段的输入型)
  • manifest文件的错误

Lint 发现的每个问题都有描述信息和等级,我们可以很方便地定位问题,同时按照严重程度进行解决。当然这个“严重程度”我们可以手动调节,有些原则问题不容侵犯,必须提升到 error,而有的个别问题也可以无视。
但是我们也不能过分依赖该工具,因为有些东西实际开发中会有自己的规则,有可能会出现冲突的地方。

Lint问题种类

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

Lint问题等级

| Fatal
| Error
| Warning
| Information
Ignore

检查问题列表详见 点我跳转

常见如下:

1. Correctness
    1) DuplicatedIds
    Layout中id应该唯一
    2) NewApi
    代码中使用的某些API高于Manifest中的Min SDK
    3) InconsistentArrays
    字符串国际化中,同一名字的的String-Array对应的item值不相同
    4) Registered
    Activity/Service/ContentProvider没有通过AndroidManifest注册
    5) Deprecated
    使用已经废弃的API
    6) PxUsage
    避免使用px,使用dp

2. Correctness:Messeges
    1) MissingTranslation
    字符串国际化不完全
    2) ExtraTranslation
    国际化的字符串,在默认位置(defaultlocale),没有定义

3. Security
    1) SetJavaScriptEnabled
    不确定你的程序中确实需要JavaScript就不要执行SetJavaScriptEnabled。
    2)ExportedContentProvider/ExportedReceiver/ExportedService/ExportedActivity
    ContentProvider/Receiver/Service/Activity的exported为true时,设置一个Permission,让使用者获取了Permission才能使用。
    3) HardcodedDebugMode
    不要在manifest中设置android:debuggable。
    设置它,编译的任何版本都要采用指定的debug模式。不设置,编译Eng版本采用debug模式;编译User版本采用release模式。

4. Performance
    1) DrawAllocation
    避免在绘制或者解析布局(draw/layout)时分配对象。E.g.,Ondraw()中实例化Paint对象。
    2) ObsoleteLayoutParam
    Layout中无用的参数。
    3) UseCompoundDrawables
    可优化的布局:如包含一个Imageview和一个TextView的线性布局,可被采用CompoundDrawable的TextView代替。
    4) UseSparseArrays
    尽量用Android的SparseArray代替Hashmap
    5) DisableBaselineAlignment
    如果LinearLayout被用于嵌套的layout空间计算,它的android:baselineAligned属性应该设置成false,以加速layout计算。
    6) FloatMath
    使用FloatMath代替Math。
    7) NestedWeights
    避免嵌套weight,那将拖累执行效率
    8) UnusedResources/UnusedIds
    未被使用的资源会是程序变大,并且编译速度降低。
    9) Overdraw
    如果为RootView指定一个背景Drawable,会先用Theme的背景绘制一遍,然后才用指定的背景,这就是所谓的“Overdraw”。
    可以设置theme的background为null来避免。
    10) UselessLeaf/UselessParent
    View或view的父亲没有用

5. Usability:Typography
    1) TypographyDashes
    特殊字符需用编码代替:“–”需要用“–”;“—”需要用“—”
    2) TypographyEllipsis
    特殊字符需用编码代替:“…”需要用“…”
    3) TypographyOther
    问题:“(c)”需要用“©”

6. Usability:Icons
    1) IconNoDpi
    Icon在nodpi和指定dpi的目录下都出现。
    2) GifUsage
    Image不要用GIF,最好用PNG,可以用JPG。

7. Usability
    1) BackButton
    Android中不要设计有Back的按钮,Android中一般有Back的硬按键。
    2) ButtonCase
    Button的“Ok”/“Cancel”显示大小写一定,不要全大写或全小写。有标准的资源的字符串,不要自己再定义,而要用系统定义的:@android:string/ok和@android:string/cancel

8. Accessibility
    1) ContentDescription
    ImageView和ImageButton应该提供contentDescription

    9. Internationalization
    1) HardcodeText
    硬编码的字符串应该在资源里定义
    2) EnforceUTF8
    所有XML资源文件都应该以UTF-8编码

    ...

命令行执行:

命令行路径

ADT:your ‘sdk’ dir\tools\lint.bat
AS:your ‘sdk’ dir\tools\bin\lint.bat

命令行使用

在’lint.bat’同级目录打开cmd

您可以通过’–help’获取对应的帮助

Issue列表

lint –list list只是issue的id和summary的列表
lint –show show显示详细的issue信息

disable/enable/check

lint –disable <list>
lint –enable <list>
lint –check <list>
Android-Lint所支持要检测的Issue列表,默认有检查(Severity为非Ignore)和忽略(Severity为Ignore)之分。

可以用disable不检查指定<list>中默认要检查的id或category;用enable检查指定<list>中默认忽略的id或category;用check只检查指定<list>中的id或category。
1. disable/enable是在default列表的基础上,disable/enable给定列表里的;check是只检查列表里的。
2. <list>是issue id或category列表,用逗号隔开。

生成html/xml报表

lint –html <target_filename> <proj_dir>生成html格式的报告
lint –html <target_filename> --url filepath=url生成的html文件中,还会引用别的文件,可以通过url参数替换其中的地址,使其指向公共访问的地方
lint –simplehtml <target_filename> <proj_dir>生成格式简单的html报告
lint –xml <target_filename> <proj_dir>生成html格式的报告

自定义分析策略

lint –config <custom-lint_config_filename> <target_filename> <proj_dir>

虽然disable/enable/check选项可以改变本次检查的问题行为,但是下次还要再次指定。可以通过config选项指定默认的全局配置文件。
注意:如果项目中已经有lint.xml文件,对于某条issue的检查来说,先用项目中lint.xml的规则,然后是config指定的规则,最后才是系统默认的规则。

lint在Gradle中可以使用”gradlew lint”命令行(Windows),”./gradlew lint”(mac)执行。详细可移步至:https://developer.android.com/studio/write/lint.html#commandline

IDE集成操作

Eclipse

打开方式

  1. 右键项目 > Android Tools > Run Lint:xxx 如下图:
    aaa
  2. 导航栏 > Run Lint 如下图(可选择check范围):
    这里写图片描述

分析结果

这里写图片描述

设置

可以在这里更改Lint检查等级等…如下图:
这里写图片描述

Android Studio

打开方式

  1. 选择要分析的项目或者文件、文件夹,从菜单栏,选择Analyze > Inspect Code
    这里写图片描述
  2. 选择检查范围
    这里写图片描述
    显示在Spectify Inspection Scope对话框的选项组合区取决于是否你选择了一个项目,文件夹或者文件。你可以通过选择其它的单选按钮来改变你想检查的文件。查看Spectify Inspection Scope对话框中所有可选项的说明;
    当你选择一个项目,文件或者目录,Specity Sinpection Scope对话框显示你选择的项目,文件或者目录的路径;
    当你选择超过一个项目,文件,或者目录,Specity Inspection Scope对话框显示为你选中的文件显示一个选中的单选按钮;
  3. 展示检查结果
    这里写图片描述
    在左边的面板树视图中,通过展开和选择错误类型,类别和问题来查看检查的结果;
    右边面板显示了选中的错误类型,类别和文件的检查报告,提供了错误的名字和位置。在适当的地方,检查报告展示了如问题摘要等其它信息来帮助你修改问题;
    在左边面板树视图,右键单击类型,类别和问题来显示上下文菜单;
    基于上下文,你可以执行所有或者一些如下操作:跳转到源码,排除和包含选中的选项,抑制问题,编辑设置,管理检查警告,和重新运行检查;

根据名称检查

以筛选无用的资源为例:
这里写图片描述
这里写图片描述

创建自定义范围

这里写图片描述
这里写图片描述
从下拉列表中,记得选择Project,有效的项目列表显示在下面,按照图示的样式选择过滤,这个结构符合我们平时的习惯;
Include 包含这个文件夹和它的文件,但是不包含任何它的子文件夹
Include Recursively 包含这个文件夹和所有它的文件,和子文件和它们的文件
Exclude 不包含这个文件夹和它的文件,但是不包含任何它的子文件夹
Exclude Resursively 不包含这个文件夹和所有它的文件,和子文件和它们的文件

如果你选择文件夹,点击Exclude Recursively,这个文件夹以及所有子文件夹和文件变为绿色;
如果你选择文件夹下绿色的文件,点击Exclude,文件不在为绿色,但是文件下的其它所有文件还是绿色的;

设置

如下图:
这里写图片描述

高级扩展

自定义lint

lint简介

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的定制才起作用。
e.g

<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- Disable the given check in this project -->
<issue id="IconMissingDensityFolder" severity="ignore" />
<!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
<issue id="ObsoleteLayoutParam">
    <ignore path="res/layout/activation.xml" />
    <ignore path="res/layout-xlarge/activation.xml" />
</issue>
<!-- Ignore the UselessLeaf issue in the specified file -->
<issue id="UselessLeaf">
    <ignore path="res/layout/main.xml" />
</issue>
<!-- Change the severity of hardcoded strings to "error" -->
<issue id="HardcodedText" severity="error" />
</lint>

禁用lint检查

在java中禁用检查

在需要禁用的地方添加添加”@SuppressLint”注解,抑制在Java文件中的所有lint问题检查,使用all关键字。
e.g

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
//下面的例子展示了如何在FeedProvider类中关闭ParserError问题检查;
@SuppressLint("ParserError")
public class FeedProvider extends ContentProvider {...
在xml中配置lint检查

可以使用tools:ignore属性来禁止Lint对你的XML文件指定部分进行检查。在lint.xml文件中加入下面的命名空间,Lint工具才能识别这些属性。

xmlns:tools="http://schemas.android.com/tools"

e.g

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="UnusedResources" >
    <TextView
        android:text="@string/auto_update_prompt" />
</LinearLayout>

为了禁止多个问题,使用逗号分隔的字符串列出要禁止的问题。
tools:ignore=”NewApi,StringFormatInvalid”
为了在XML元素中抑制所有的lint问题检查,使用all关键字。
tools:ignore=”all”

在Gradle中配置lint选项

Gradle的Android插件允许你在你模块级别的build.gradle文件中,使用lintOption{}块配置一些lint选项,例如执行或者忽略什么检查。下面的代码片段向你展示了你可以配置的一些属性。
e.g

android {
  ...
  lintOptions {
    // Turns off checks for the issue IDs you specify.
    disable 'TypographyFractions','TypographyQuotes'
    // Turns on checks for the issue IDs you specify. These checks are in
    // addition to the default lint checks.
    enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
    // To enable checks for only a subset of issue IDs and ignore all others,
    // list the issue IDs with the 'check' property instead. This property overrides
    // any issue IDs you enable or disable using the properties above.
    check 'NewApi', 'InlinedApi'
    // If set to true, turns off analysis progress reporting by lint.
    quiet true
    // if set to true (default), stops the build if errors are found.
    abortOnError false
    // if true, only report errors.
    ignoreWarnings true
  }
}
...

推荐定制的路线:

在Eclipse中基于现有的问题,逐个分析并解决,然后我们就能得到一个Eclipse自动生成的lint.xml这个定制文件;
然后这个lint.xml用于Eclipse和/或命令行下进行后续的检查;
后续发现的问题再进一步处理,逐步完善lint.xml这个定制文件。

特别地,一旦项目组决定采用Android-Lint,定制Lint规则要有对项目和团队负责的专人来定制执行。Lint的目的是尽量多的暴露问题,解决问题,而个人会有刻意隐藏/规避错误的倾向。所以,验收的时候,用大家讨论认可的Lint规则做统一的执行检查。

jenkins插件

https://wiki.jenkins-ci.org/display/JENKINS/Android+Lint+Plugin
Android Lint Plugin可以解析lint生成的xml结果文件,并生成趋势图、详细条目、dashboard展示空间等
需要注意该插件仅用于解析lint的xml report,在此之前你需要自行调用命令行生成结果文件。
效果图


参考文章:
[1] http://tools.android.com/tips/lint
[2] http://blog.csdn.net/eofguo/article/details/51210652
[3] http://blog.csdn.net/thl789/article/details/8037473
[4] http://qa.blog.163.com/blog/static/19014700220142248543346/
[5] http://blog.csdn.net/u011240877/article/details/54141714
[6] http://blog.csdn.net/p106786860/article/details/54187138

猜你喜欢

转载自blog.csdn.net/luzhenyuxfcy/article/details/79398761