Android Studio官方文档之用注解检查改善代码质量

来源:互联网 发布:coc女王数据 编辑:程序博客网 时间:2024/06/13 06:26

Android Studio官方文档之用注解检查改善代码质量

本文由peterZhang翻译,jkYishon审校。

1、前言

使用代码检查工具(例如Lint)能帮助我们找到一些问题并且可以提高我们代码的质量。但是识别像资源id,比如识别字符资源、颜色资源或者其他类型的资源,监测工具是不能告诉我们你是引用了一个字符串资源还是颜色资源的。这就意味着,即使你使用了代码检测,但你的应用程序在运行的时依然可能会失败。

注解提供了一个能检测代码的暗示就像Lint一样,它能监测一些更细小的问题。注解能够添加在变量、参数以及方法的返回值上,并且检查他们,能过让他们通过。除了使用代码检查工具外,注解能帮助你察觉空指针和资源类型冲突这类错误。

想了解更多关于代码检测的工具请看导入代码标注线(Improving Your Code with lint)

Android支持多种注解,在你的代码中能够插入在方法、参数、返回值,例如

@Nullable 可以为空

@NonNull 不能为空

@StringRes 资源类型只能是字符串资类型

@DrawablesRes 资源类型只能是图片资类型

@ColorRes 资源类型只能是颜色资源类型

@InterPolatorRes 资源类型是查直器类型

@AnyRes 资源类型是R.的资源类型

@UiThread 调用一个UI线程

对于注解列表,有两种方式可以支持,一种是添加 Support-Annotations库支持,另一种是默认自动导入import android.support.annotation. statement包。

SDK管理包中的支持注解库可以被用在Android Stuido中也可以用在其他的开发工具中。

2、增加一个基本的注解(Adding Basic Annotations)

在代码中添加一个注解,首先要添加一个支持注解库的依赖。

1.选择File > Project Structure

2.在Project Stucture的弹出的对话框中,选择想要添加模块下的Dependencies选项卡页面。

3.点击右侧绿色+号图标后,会有一个库的依赖选项(Library dependency)。

4.在选择依赖库的对话框中,选择support-annotations库并且点击OK

gradle构建文件会更新对注解的依赖。

你也可以手动的在构建文件中添加依赖,比如像

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

Support-Annotations库是修饰所支持的注解的库,使用里面的方法可以尽可能的去检查代码中潜在的问题。

如果在一个库中包括了注解的话,使用Android构建插件去构建Android文档工具在这个库中,在annotations.zip解压包文件中这些注解被包括在XML格式的一部分的,

开始在Android Studio中检查一段代码,包括验证注解和自动标注线检测,可以选择分析(Analyze)菜单下 检查代码(Inspect Code)选项,Android Studio通过指示注解冲突在显示器中显示冲突信息并且建议提出解决问题的方案。

3、增加空指针注解Adding Nullness Annotations

增加@Nullable和@NonNull的注解检查给出的变量、参数、返回值是不是可以为空,例如如何当前传递的参数包括了一个空值,那么在参数前增加一个@NonNull的注解的参数在构建代码的时候会出现一个不能为空的警告。

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

为空性分析(Nullability Analysis)

Android Studio支持一个为可否为空的分析,可以自动的推断和插入空指针注解在你的代码中。一个为空性分析能合同整个代码中的层次结构检测方法:

  • 调用方法返回null(Calling methods that can return null)
  • 方法不应该返回null(Methods that should not return null)
  • 变量,如字段、局部变量和参数,可以为空(Variables, such as fields, local variables, and parameters, that can be null)
  • 变量,如字段、局部变量和参数,不能空值(Variables, such as fields, local variables, and parameters, that cannot hold a null value)

在检测到的位置,分析能自动插入适当的注解。

在Android Studio中运行一个为空性分析,选择菜单Analyze下的Infer Nullity选项,AndroidStudio会在代码检测到的位置自动的添加@Nullable和@NonNull注解。然后运行一个空的分析,它能更好的实践验证注入注解。

注意:当增加为空性注解时,会自动建议java平台的@Nullable和@NotNull注解代替Android为空性注解并可能导入相应的库。然而,Android Studio标注线能检查出是否是Android的为空性注解。当验证你的注解时,确认了你在项目中使用的空注解,那么标注线检查器能正确的通知你在代码检查的时候。

3、增加资源注解(Adding Resource Annotations)

确认资源的类型是非常有用的,例如图片文件资源和字符串资源,他们都是通过在数字类型资源引入到参数中的,代码期望引入一个特殊的资源例如引入一个图片资源,但是实际上可以引入一个其他int类型的资源像字符串资源。

假如增加一个@StringRes的注解去检查当前参数资源是否是一个字符串,在代码检查的过程中,如果不是字符串这个注解就会出现警告不是一个字符串资源。

本例专门对@StringRes注解是否真的能检查当前资源是否是个字符串。

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

注解其他的资源类型如 @DrawableRes、@DimenRes、@ColorRes和@InterpolatorRes能被增加可以添加使用相同的注解格式在代码检查运行的时候。

4、增加线程注解(Adding Thread Annotations)

线程注解能检查一个方法中是否是一个特殊类型的线程。以下线程注解是被支持的:

  • Ui线程(@UiThread)
  • 主线程(@MainThread)
  • 工作线程(@WorkerThread)
  • 绑定线程(@BinderThread)

注意:@MainThread和@UiThread注解是可以相互交换的,因此方法调用这些类型的注解是被允许的。

如果所有的方法要求使用同一个线程,你可以增加一个单例线程注解在类中所有方法来验证相同类型的线程。

一个常见的线程注解是验证是否在UI线程上进行异步任务类的方法重写后台运行和发布结果。

5、增加值约束注解(Adding Value Constraint Annotations)

可以使用数字约束注解(@IntRange)、双精度型约束注解(@FloatRange)、大小型约束注解(@Size)来检查参数中的值。

@IntRange注解能检查参数值是不是在一个给定的范围内,例如检查透明度参数值是在0到255范围内的

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

@FloatRange注解能检查参数值是否是一个在双精度范围的值,的检查透明度参数包括一个从0.0到1.0的双精度范围

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

@Size注解可以检查集合的大小,字符串的长度,例如使用@Size(min = 1)的注解检测一个集合是否是空的,或者使用@Size(2)的注解检查集合里是否有2个值,以下是检查集合中最少包含一个元素:

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

6、增加权限注解(Adding Permission Annotations)

使用@RequiresPermission注解检查一个方法是否有权限。检查单个权限从权限清单中,使用anyOf属性。检查塞入一个权限使用allOf属性,以下例子注解setWallpaper方法是否有permission.SET_WALLPAPERS 权限

    @RequiresPermission(Manifest.permission.SET_WALLPAPER)    public abstract void setWallpaper(Bitmap bitmap) throws IOException;

这个例子允许copyFile()方法有一个写到内存卡中的权限

    @RequiresPermission(allOf = {    Manifest.permission.READ_EXTERNAL_STORAGE,    Manifest.permission.WRITE_EXTERNAL_STORAGE})    public static final void copyFile(String dest, String source) {    ...    }

7、增加检查结果注解(Adding CheckResults Annotations)

使用检查结果注解时是检查方法的结果是否返回实际上的的值,以下展示了一个检查权限的方法是否返回一个实际的引用。它还可以建议开发人员以一个enforcePermission方法名字作为替换。

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

8、增加继承Super关键字注解(Adding CallSuper Annotations)

使用@CallSuper注解可以检查方法重写继承实现的这个方法。以下例子注解onCreat方法中重写方法是否含有supuer.onCreat();

    @CallSuper    protected void onCreate(Bundle savedInstanceState) {}

9、增加枚举注解(Creating Enumerated Annotations)

使用@IntDef和@StringDef注解,能检测在创建的枚举类类型是数字类型和字符类型在赋值时是否是其他的类型。

以下例子阐明创建一个枚举注解的步骤,确保值作为一个方法的参数是固定的常量

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 annotationpublic @interface NavigationMode {}//Declare the constantspublic 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@NavigationModepublic abstract int getNavigationMode();//Attach the annotationpublic abstract void setNavigationMode(@NavigationMode int mode);

当你构建代码的时候,一个警告就会产生如果这个mode参数不是(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, or NAVIGATION_MODE_TABS)中一个固定的常量。

你也可以固定在一个flag标记值在注解中,这个标记能检查是否一个参数返回值是有效的。例如创建一个展示是DISPLAY_ constants有效的列表菜单DisplayOptions注解。

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 {}...

当你构建代码时,如果修饰的参数返回值不是有效的就会出现一个警告。

0 0