Improving Code Inspection with Annotations——使用诠注改善代码检查

Improving Code Inspection with Annotations——使用注解改善代码检查

使用代码检查工具,例如lint,可以帮助你检查问题并改善代码,但是检查工具也就只能推断这么多。例如Android资源id,使用int来标识字符串,图形,颜色和其他资源类型,而检查工具不能告诉你当在需要指定一个颜色的地方你指定了一个字符串资源。这种情况意味着你的应用可能渲染不正确或根本运行失败,即使你使用了代码检查。

注解允许你提供暗示给像lint的代码检查工具,来帮助检测这些更精细的代码问题。它们以元数据标签添加,你可以附在变量,参数,和返回值来检查方法返回值,传递的参数,局部变量和字段。当使用代码检查工具,注解可以帮助你检测像空指针异常和资源类型冲突问题。

关于启用lint检查和运行lint,参考《使用lint改善你的代码》。

Android支持大量的注解来插入到代码中的方法,参数和返回值,例如:

  • @Nullable
    可以为空。
  • @NonNull
    不可为空。
  • @StringRes
    引用一个string资源。
  • @DrawableRes
    引用一个Drawable资源。
  • @ColorRes
    引用一个Color资源。
  • @InterpolatorRes
    引用一个Interpolator资源。
  • @AnyRes
    引用任何类型的R.资源。

查看完整的支持的注解列表,要么检查Support-Annotations库的内容,要么使用自动完成特性来显示 import android.support.annotation 语句的可用属性。SDK Manager打包Support-Annotations库到Android Support Repository对于使用Android Studio和到Android Support Library对于使用其他Android开发工具的。

加入注解到代码,首先添加一个Support-Annotations库的依赖。在Android Studio中,在 build.gradle 文件添加依赖。

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

Support-Annotations库使用支持的注解装饰,因此使用这个库的方法和资源自动检查代码的潜在问题。

如果你在一个库中包含注解,并使用Android Plugin for Gradle来构建这个库的Android存档,注解会作为存档的一部分以XML格式包含在 annotations.zip 文件。

在菜单选项中选择Analyze > Inspect Code来从Android Studio启动代码检查,Android Studio包含验证注解和自动lint检查。Android Studio在整个代码中显示冲突信息来标识注解冲突和建议可能的解决方案。

添加空判断注解

添加@Nullable和@NonNull注解来检查变量,参数和返回值是否为空。例如,如果包含一个作为参数传递给方法的空值的局部变量有@NonNull注解附在这个参数上,构建代码会生成一个警告标示一个不可为空冲突。

这个例子在 contextattrs 参数附上@NonNull注解来检查传递的参数值不为空。

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

记住:Android Studio支持运行一个为空性分析来自动推断和在代码中插入空判断注解。

添加资源注解

添加@StringRes注解来检查一个资源参数包含一个R.string引用。在代码检查时,如果这个参数没有传递一个R.string引用,注解会生成一个警告。

因为Android Drawables和R.string资源都以整形传递,所以验证资源类型很有用。代码中期待一个Drawable引用的参数可以被传递一个int类型的引用,但实际上引用的是一个R.string资源。

这个例子附上@StringRes注解到resId参数来验证它真的是一个字符串资源。

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

其他资源类型的注解,例如@DrawableRes,@ColorRes和@InterpolatorRes也可以用同样注解格式被添加并在代码检查时运行。

创建枚举注解

使用@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 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,NAVIGATION_MODE_TABS),会生成一个警告。

你也可以定义一个有flag的注解来检查一个参数或返回值引用合法格式。这个例子用一个合法的DISPLAY_常量列表创建了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 {}

...

当你构建含有注解flag的代码,如果被修饰的参数或返回值没有引用合法格式,会生成一个错误。

原文链接:
http://developer.android.com/tools/debugging/annotations.html

本博客会持续对Debug系列的以下文章进行翻译,后面追加链接的为已翻译的:

  1. Debugging——Android应用调试
    http://blog.csdn.net/doandkeep/article/details/45173475
  2. Debugging with Android Studio——在Android Studio中调试
    http://blog.csdn.net/doandkeep/article/details/45219295
  3. Debugging from Other IDEs——在其它IDE中调试
    http://blog.csdn.net/doandkeep/article/details/45243465
  4. Using DDMS——使用DDMS
    http://blog.csdn.net/doandkeep/article/details/45670021
  5. Reading and Writing Logs——读写日志
    http://blog.csdn.net/doandkeep/article/details/45848897
  6. Improving Your Code with lint——使用lint优化代码
    http://blog.csdn.net/doandkeep/article/details/46048733
  7. Optimizing Your UI——优化UI
    http://blog.csdn.net/doandkeep/article/details/46233935
  8. Profiling with Traceview and dmtracedump
  9. Improving Code Inspection with Annotations
  10. Analyzing Display and Performance
  11. Investigating Your RAM Usage
  12. Using the Dev Tools App