使用 Lint 来检查代码

在 Android Studio 中使用 lint

在Android Studio中,当你build app的时候,Lint和IDE 检查会自动运行。

使用 File > Settings > Editor > Inspections 菜单可以打开检查配置界面

使用Android Studio,可以在build.gradle文件中添加 lintOptions 属性 可以对Lint 的检查做相关的设置。下面是示例代码:

android {    lintOptions {       // set to true to turn off analysis progress reporting by lint       quiet true       // if true, stop the gradle build if errors are found       abortOnError false       // if true, only report errors       ignoreWarnings true       }       ...    }

在指定目录上右击,在右击菜单中选择Analyze > Inspect Code 就可以进行手动的Lint代码检查。

在命令行中跑 lint

检查工程目录下的所有文件:

lint [flags] <project directory>

使用下面命令可以扫描myproject 目录下的所有文件以及子文件。参数MissingPrefix 表示只扫描缺少Android 命名前缀的XML属性。

lint --check MissingPrefix myproject 

通过命令来查看使用方法和参数:

lint --help

配置lint

在Android Studio中配置lint

有两种方法可以看到Lint的warnings和errors 结果:
- 编辑器中提示文字。Lint会黄色高亮有问题的代码,或使用红色下划线指示严重的问题。
- 手动Analyze > Inspect Code 之后,在检查结果窗口中。

设置默认的Lint 检查:
1. 打开项目,选择 File > Other Settings > Default Settings,选择 Editor > Inspections.
2. 在Profile 选项中,选择 Default or Project Default来选择是全局作用域还是project作用域。
3. 在窗口中进行设置。

配置手动执行的Lint检查:
1. 打开项目,选择你要测试的目录。使用Analyze > Inspect Code.
2. 在指定检查范围弹出框中,选择检查scope和profile。scope指定哪些文件你想要分析,profile指定你想要执行的Lint checks。

配置 lint 文件

可以使用lint.xml来指定Lint的检查属性。手动创建这个文件的话,把它放到project的根目录下。 如果你是通过Android Studio来配置检查属性,lint.xml会自动创建在project根目录下。

lint.xml结构如下,由 父tag包含一个或多个 子元素组成,每个 指定一个唯一的由Lint定义过的id属性。

<?xml version="1.0" encoding="UTF-8"?><lint>        <issue id="IconMissingDensityFolder" severity="ignore" />        <issue id="ObsoleteLayoutParam">        <ignore path="res/layout/activation.xml" />        <ignore path="res/layout-xlarge/activation.xml" />    issue>        <issue id="UselessLeaf">        <ignore path="res/layout/main.xml" />    issue>        <issue id="HardcodedText" severity="error" />lint>

在Java和XML源文件中配置lint 检查

可以在java和XML源文件中禁用Lint检查.

  • 在java文件中
    @SuppressLint 注解可以让Java class 或者方法不用Lint检查。

    关闭”NewApi”问题的检查

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

    关闭”ParserError”的问题检查

    @SuppressLint("ParserError")public class FeedProvider extends ContentProvider {

    关闭Java文件中的所有的检查

    @SuppressLint("all")
  • 在XML文件中
    使用tools:ignore属性来禁止XML文件制定区域的Lint 检查。父控件的ignore属性会被子控件继承。
    关闭”UnusedResources “的问题检查。

        <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"

    关闭所有的问题检查

    tools:ignore="all"

使用Annotations来检查代码 (Support-Annotations library)

Annotations 可以给代码检查工具提供一些提示,来帮助检查微妙的代码问题。
Annotations以元数据的方式添加到 变量、参数、一个方法中的输入参数、返回值等。
当使用了代码检查工具, annotations 可以帮助检查这些问题,比如空指针异常和资源文件类型冲突。

添加基本的注解

想要在代码中使用注解,需要添加 Support-Annotations 库。
- 可以通过Android Studio 来添加
- 或者直接在gradle.xml中添加

dependencies {    compile 'com.android.support:support-annotations:23.3.0'} 

添加 Nullness Annotations

@Nullable and @NonNull annotations 可以检查一个变量、参数或返回值的null情况。

使用@NonNull 来检查传入的参数不能为空。

import android.support.annotation.NonNull;...    /** Add support for inflating the  tag. */    @NonNull    @Override    public View onCreateView(String name, @NonNull Context context,      @NonNull AttributeSet attrs) {      ...      }...

Nullability Analysis

Android Studio 支持通过nullability 分析来在代码中动态的推断和插入nullness annotations。为空性分析根据贯穿方法树的几个约定来进行扫描:
- 方法可以返回空
- 方法不可以返回空。
- 变量可以为空,比如本地变量和参数。
- 变量不能为空,比如本地变量和参数。

这个分析完成后,被检查的地方会动态的加入合适的null annotations。

在 Android Studio 中 进行 nullability的检查,选择Analyze > Infer Nullity
Android Studio会插入 @Nullable and @NonNull annotations 在需要检查的位置。在空指针分析完成后,最好检验一下被注入的annotations。

添加 Resource Annotations

Resource Annotations 校验传入的参数是否为指定的资源类型
@StringRes
@DrawableRes
@DimenRes
@ColorRes
@InterpolatorRes

import android.support.annotation.StringRes;...    public abstract void setTitle(@StringRes int resId);    ...

添加 Thread Annotations

Thread annotations 校验一个方法是否在指定的线程中被调用。有以下4中类型:
@UiThread
@MainThread
@WorkerThread
@BinderThread

@MainThread and the @UiThread 可以互换。

添加 Value Constraint Annotations

@IntRange, @FloatRange, @Size 校验传递过来的参数值。

@IntRange 校验是否在指定的整形范围内。例子说明 alpha 参数包含在 0 ~ 255 之间:

public void setAlpha(@IntRange(from=0,to=255) int alpha) { … }

@FloatRange 检验是否在指定的浮点型范围内。比如确保alpha参数在0.0 to 1.0之间:

public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}

@Size 校验一个容器或数组的长度。比如,使用@Size(min=1) 来检查一个容器不为空,使用@Size(2)来校验容器确定只有两个值。比如 确定location 数组知识包含一个元素:

int[] location = new int[3];button.getLocationOnScreen(@Size(min=1) location);

添加Permission Annotations

@RequiresPermission 校验方法调用者的权限。 anyOf 属性用于检查满足一种一个, allOf属性用于检查满足所有 attribute.

setWallpaper 方法必须要有permission.SET_WALLPAPERS 权限.

@RequiresPermission(Manifest.permission.SET_WALLPAPER)public abstract void setWallpaper(Bitmap bitmap) throws IOException;
@RequiresPermission(allOf = {    Manifest.permission.READ_EXTERNAL_STORAGE,    Manifest.permission.WRITE_EXTERNAL_STORAGE})public static final void copyFile(String dest, String source) {    ...}

添加 CheckResults Annotations

@CheckResults 校验方法接口或者返回值是否真的被使用了。
下面的例子表示checkPermissions 方法确定返回值被使用了。如果没使用,就会建议使用 enforcePermission方法来替代。

@CheckResult(suggest="#enforcePermission(String,int,int,String)")public abstract int checkPermission(@NonNull String permission, int pid, int uid);

添加 CallSuper Annotations

使用@CallSuper 注解 校验 覆写的方法 需要调用父类的实现方法。
例子,覆写onCreate的方法必须调用super.onCreate()。

 @CallSuperprotected void onCreate(Bundle savedInstanceState) {}

创建Enumerated Annotations

使用 @IntDef@StringDef 注解 可以创建一个integer 和 string 类型的集合用来校验 其他变量的引用类型,比如传入set中的引用类型。

import android.support.annotation.IntDef;...public abstract class ActionBar {    ...    //Define the list of accepted constants    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})    //Tell the compiler not to store annotation data in the .class file    @Retention(RetentionPolicy.SOURCE)    //Declare the NavigationMode annotation    public @interface NavigationMode {}    //Declare the constants    public static final int NAVIGATION_MODE_STANDARD = 0;    public static final int NAVIGATION_MODE_LIST = 1;    public static final int NAVIGATION_MODE_TABS = 2;    //Decorate the target methods with the annotation    @NavigationMode    public abstract int getNavigationMode();    //Attach the annotation    public abstract void setNavigationMode(@NavigationMode int mode);

译代码的时候,如果mode 类型不在定义中的(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, or NAVIGATION_MODE_TABS)时,会有警告产生。

使用flag 可以检查一个参数或者返回值是否引用类型是否在指定的格式中。

import android.support.annotation.IntDef;...@IntDef(flag=true, value={        DISPLAY_USE_LOGO,        DISPLAY_SHOW_HOME,        DISPLAY_HOME_AS_UP,        DISPLAY_SHOW_TITLE,        DISPLAY_SHOW_CUSTOM})@Retention(RetentionPolicy.SOURCE)public @interface DisplayOptions {}...

参考文档

Improve Your Code with Lint
Improve Code Inspection with Annotations
support-annotations
提高代码质量-工具篇

更多相关文章

  1. Android(安卓)databinding(详解三)--自定义属性使用
  2. android 莫名出现Conversion to Dalvik format failed: Unable t
  3. Android应用的自动升级、更新模块的实现
  4. 【Android(安卓)界面效果34】Android里Service的bindService()和
  5. android电话流程(打电话,接电话,挂断电话)
  6. Android(安卓)Studio使用Volley
  7. Android(安卓)Handler机制之Handler 、MessageQueue 、Looper
  8. Android(安卓)ContentProvider总结
  9. Android(安卓)控件框架

随机推荐

  1. java-universal-tween-engine
  2. UBUNTU搭建android SDK开发环境
  3. Android开发工具之Android(安卓)Studio--
  4. Android(安卓)Material Design Library系
  5. Android(安卓)onItemLongClick+onCreateCo
  6. Android线程池机制封装
  7. Android(安卓)studio常用设置和快捷键
  8. 【小知识点总结】保存android日志logcat
  9. 【Android(安卓)开发教程】ListView的扩
  10. RN(react-native)踩坑实录--编写项目