您的位置:首页 > 移动开发 > Android开发

Android注解支持(Support Annotations)

2015-12-08 12:45 477 查看

 

原文地址:http://tools.android.com/tech-docs/support-annotations

Android Support Library从19.1版本开始引入了一个新的注解库,其中包括了很多有用的元注解,可以用来修饰代码并且帮助发现bug。Support Library本身也使用了这些注解,当使用Support Library库的时候,Android Studio实际上已经在基于这些注解来检查代码中的潜在问题了。

使用注解库

这些注解不是默认加载的,它们被包装为一个单独的库。Support Library现在是由一些更小的库组成的,包括:v4-support、appcompat、gridlayout、mediarouter等等。

添加注解的最简单的方法就是打开Project Structure对话框。首先在左边选中module,然后右边选中Dependencies标签,点击“+”号按钮,选择Library Dependency。如果SDK中已经包括了Android Support库,那么注解支持库就会显示在快捷选择列表中了,只需要点击选择就可以。

步骤1:点击Project Structure按钮



步骤2:选中Dependencies标签,点击“+”号按钮



步骤3:在下拉列表中选中support-annotations库



点击OK确定,这将会修改build.gradle文件。当然也可以手动在Gradle中添加如下依赖:

[plain]
view plaincopyprint?

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

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

Nullness注解

@Nullable注解可以用来标识特定的参数或者返回值可以为null。
类似的,@NonNull注解可以用来标识参数不能为null。

如果一个局部变量已经被知道为null,然后它被作为参数传递给了一个方法,并且这个参数被标记为@NonNull,那么IDE会警告这样做可能引发潜在的Crash问题。

v4 support library中的示例代码:

[java]
view plaincopyprint?

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

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
...

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

Resource Type Annotations(资源类型注解)

资源在Android中作为整型值来传递。这意味着希望获取一个drawable作为参数的代码很容易被传递了一个string类型的资源,因为他们资源id都是整型的,编译器很难区分。

Resource Type Annotations在这种条件下可以提供类型检查。例如,对一个int型参数添加@StringRes注解,如果传递的不是R.string类型的引用都会被编译器标记。



ActionBar的例子

[java]
view plaincopyprint?

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

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

IntDef/StringDef: Magic Constant Annotations(常量注解)

int型除了被作为资源引用传递之外,还经常被作为一种“枚举”类型来使用。
@IntDef注解让你可以实现一种类似于"typedef"的效果,你可以在创建一个注解的同时列出所有可用的有效值,然后再使用这个注解。也就是说@IntDef是用来修饰注解的注解(元注解),用它所修饰的注解在使用时就限定了被修饰对象的可取值范围。
来看以下appcompat 库中实际的例子:

[java]
view plaincopyprint?

import android.support.annotation.IntDef;  
...  
public abstract class ActionBar {  
    ...  
    @Retention(RetentionPolicy.SOURCE)  
    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})  
    public @interface NavigationMode {}  
  
    public static final int NAVIGATION_MODE_STANDARD = 0;  
    public static final int NAVIGATION_MODE_LIST = 1;  
    public static final int NAVIGATION_MODE_TABS = 2;  
  
    @NavigationMode  
    public abstract int getNavigationMode();  
  
    public abstract void setNavigationMode(@NavigationMode int mode);  

import android.support.annotation.IntDef;
...
public abstract class ActionBar {
...
@Retention(RetentionPolicy.SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LI
cdec
ST, NAVIGATION_MODE_TABS})
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);


以上例子中创建了一个新的注解(public @interface NavigationMode)然后我们对这个注解使用了元注解@IntDef,然后列出了所有可能的值(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS),然后我们再用这个注解修饰了一个方法(getNavigationMode()),于是这个方法的返回值就被限定为NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS这三个枚举值中的一个了。

使用这个注解后,如果返回值和传递的参数值不在枚举值中,IDE工具就会标记出不符合注解要求的代码。

还可以通过@IntRef注解指定一个int型变量是一个“flag”类型,“flag”类型意味着它的取值可以是一些常量进行位运算(|、&、^)之后的结果
请看如下注解示例:

[java]
view plaincopyprint?

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

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


于是被@DisplayOptions注解修饰的变量可以接受@InfDef列出的值或者这些值相互位运算的结果,例如DISPLAY_USE_LOGO | DISPLAY_SHOW_HOME。

最后,这个注解还有一个String版本的类型——@StringDef,它和@IntDef的使用目的是一样的,只是对象是String类型的值。这个注解使用的场景并不是很常见,但是却可以很好地限定允许向Activity#getSystemService方法传递的字符串常量的范围:



(以上注解其实是基于IntelliJ的MagicConstant Annotation,你可以在这里获取更为详细的信息:http://blog.jetbrains.com/idea/2012/02/new-magic-constant-inspection/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: