Android 注解指南

Android 注解指南

来源 https://juejin.im/entry/58fc7ca744d9040069e65197

 

日常开发中,注解能够帮助我们写出更好更优秀的代码,为了更好地支持 Android 开发,在已有的 android.annotation 基础上,Google 开发了 android.support.annotation 扩展包,共计50个注解,帮助开发者们写出更优秀的程序。

官网链接:developer.android.google.cn/reference/a…developer.android.google.cn/reference/a…

一览

注解名 释义 修饰类型
AnimatorRes 用于描述一个整型的参数或字段,或者是一个期望返回 animator 资源引用的方法(例如:android.R.animator.fade_in) 参数、字段、方法
AnimRes 用于描述一个整型的参数或字段,或者是一个期望返回 anim 资源引用的方法(例如:android.R.anim.fade_in) 参数、字段、方法
AnyRes 用于描述一个整型的参数或字段,或者是一个期望返回任意资源引用的方法 参数、字段、方法
AnyThread 被注解的元素可以在任意线程被调用 方法、构造器、类、接口、枚举
ArrayRes 用于描述一个整型的参数或字段,或者是一个期望返回 array 资源引用的方法(例如:android.R.array.phoneTypes) 参数、字段、方法
AttrRes 用于描述一个整型的参数或字段,或者是一个期望返回 attr 资源引用的方法(例如:android.R.attr.action) 参数、字段、方法
BinderThread 用于描述一个方法、构造器、类、接口、枚举应该运行在 binder 线程 方法、构造器、类、接口、枚举
BoolRes 用于描述一个整型的参数或字段,或者是一个期望返回 boolean 资源引用的方法 参数、字段、方法
CallSuper 用于描述子类方法,希望它们重写父类方法时也要通过 super.() 调用父类方法 方法
CheckResult 用于描述一个方法,如果它的返回值被忽略了,那么就会报错 方法
ColorInt 用于描述一个整型的参数或字段,或者是一个期望返回 int 类型颜色值的方法 参数、字段、方法
ColorLong 用于描述一个整型的参数或字段,或者是一个期望返回 long 类型颜色值的方法 参数、字段、方法
ColorRes 用于描述一个整型的参数或字段,或者是一个期望返回 color 资源引用的方法(例如:android.R.color.black) 参数、字段、方法
DimenRes 用于描述一个整型的参数或字段,或者是一个期望返回 dimension 资源引用的方法(例如:android.R.dimen.app_icon_size) 参数、字段、方法
Dimension 用于描述一个整型的参数或字段,或者是一个期望返回 dimension 的方法 参数、字段、方法、注解
DrawableRes 用于描述一个整型的参数或字段,或者是一个期望返回 drawable 资源引用的方法(例如:android.R.attr.alertDialogIcon) 参数、字段、方法
FloatRange 描述一个参数、字段或方法的返回值是一个指定范围内的 float 或 double 类型的值 参数、字段、方法
FractionRes 用于描述一个分数类型的参数或字段,或者是一个期望返回 fraction 资源引用的方法 参数、字段、方法
HalfFloat 用于描述一个半精度类型的参数或字段,或者是一个期望返回半精度值的方法 参数、字段、方法
IdRes 用于描述一个整型的参数或字段,或者是一个期望返回 id 资源引用的方法(例如:android.R.id.copy) 参数、字段、方法
IntDef 用于描述一个注解,然后再用这个被描述的注解去描述一个整形的参数或字段,或者是一个期望返回值是显示声明常量之一的方法 注解
IntegerRes 用于描述一个整型的参数或字段,或者是一个期望返回 integer 资源引用的方法(例如:android.R.integer.config_shortAnimTime) 参数、字段、方法
InterpolatorRes 用于描述一个整型的参数或字段,或者是一个期望返回 integer 资源引用的方法(例如:android.R.interpolator.cycle) 参数、字段、方法
IntRange 描述一个参数、字段或方法的返回值是一个指定范围内的 int 类型的值 参数、字段、方法
Keep 被注解的元素不会被混淆 包、参数、字段、方法、类、接口、枚举、注解、构造器
LayoutRes 用于描述一个整型的参数或字段,或者是一个期望返回 layout 资源引用的方法(例如:android.R.layout.list_content) 参数、字段、方法
MainThread 被注解的元素只能在主线程被调用 方法、构造器、类、接口、枚举
MenuRes 用于描述一个整型的参数或字段,或者是一个期望返回 menu 资源引用的方法(例如:android.R.menu.content) 参数、字段、方法
NonNull 用于描述一个参数或字段、或者一个方法的返回值不为空 参数、字段、方法
Nullable 用于描述一个参数或字段、或者一个方法的返回值可为空 参数、字段、方法
PluralsRes 用于描述一个整型的参数或字段,或者是一个期望返回 plurals 资源引用的方法(例如:android.R.plurals.ph) 参数、字段、方法
Px 用于描述一个整型的参数或字段,或者是一个期望返回像素尺寸的方法 参数、字段、方法
RawRes 用于描述一个整型的参数或字段,或者是一个期望返回 raw 资源引用的方法(例如:android.R.raw.ph) 参数、字段、方法
RequiresApi 被注解的元素只能在被给的 API 版本或更高情况下才能被调用 类、接口、枚举、方法、构造器、字段
RequiresPermission 被注解的元素需要或者可能需要一个或多个权限 注解、方法、构造器、字段
RequiresPermission.Read    
RequiresPermission.Write    
RestrictTo 被注解的元素只能在特定的范围内被访问 注解、类、接口、枚举、方法、构造器、字段、包
Size 被注解的元素需要提供其大小或长度 参数、字段、方法、注解
StringDef 用于描述一个注解,然后再用这个被描述的注解去描述一个 string 类型的参数或字段,或者是一个期望返回值是显示声明常量之一的方法 注解
StringRes 用于描述一个整型的参数或字段,或者是一个期望返回 string 资源引用的方法(例如:android.R.string.ok) 参数、字段、方法
StyleableRes 用于描述一个整型的参数或字段,或者是一个期望返回 styleable 资源引用的方法(例如:android.R.styleable.TextView_text) 方法、参数、字段
StyleRes 用于描述一个整型的参数或字段,或者是一个期望返回 style 资源引用的方法(例如:android.R.style.TextAppearance) 方法、参数、字段
TransitionRes 用于描述一个整型的参数或字段,或者是一个期望返回 transitionRes 资源引用的方法(例如:android.R.transition.fade) 方法、参数、字段
UiThread 被注解的元素只能在主线程被调用 方法、构造器、类、接口、枚举
WorkerThread 被注解的元素只能在工作线程被调用 方法、构造器、类、接口、枚举
XmlRes 用于描述一个整型的参数或字段,或者是一个期望返回 xml 资源引用的方法(例如:android.R.xml.test) 参数、字段、方法
SuppressLint Lint 静态检测工具将会忽略被注解元素的警告 类、字段、方法、参数、构造器
TargetApi Lint 静态检测工具将会以指定 API 版本对待被注解元素 类、接口、枚举、方法、构造器

示例详解

AnimatorRes

1.在 res 文件夹下创建 animator 子文件夹

2.在 animator 文件夹下创建 scale.xml 文件

<set xmlns:android="http://schemas.android.com/apk/res/android"></set>

3.在需要的地方如下调用:

@AnimatorRes
public int returnAnimator() {
    return R.animator.scale;
}

如果将 return R.animator.scale; 改成 return 1; 或 return R.string.test; 等均会报错。

AnimRes

1.在 res 文件夹下创建 anim 子文件夹

2.在 anim 文件夹下创建 scale.xml 文件

<set xmlns:android="http://schemas.android.com/apk/res/android"></set>

3.在需要的地方如下调用:

@AnimRes
public int returnAnim() {
    return R.anim.scale;
}

如果将 return R.anim.scale; 改成 return 1; 或 return R.string.test; 等均会报错。

AnyRes

在需要的地方如下调用:

@AnyRes
public int returnAny() {
    return 1;
}

如果能提前知道返回值的具体资源类型,建议将 AnyRes 换成具体的资源类型,如 StringRes 或 DrawableRes 等。

AnyThread

在需要的地方如下调用:

@AnyThread
public void test() {
    //.....
}

ArrayRes

1.在 values 文件夹下创建 arrays.xml 文件

2.在 arrays.xml 文件中添加名为 names 的子项

<resources>
    <array name="names">1, 2, 3</array>
</resources>

3.在需要的地方如下调用:

@ArrayRes
public int returnArray() {
    return R.array.names;
}

如果将 return R.array.names; 改成 return 1; 或 return R.string.test; 等均会报错。

AttrRes

1.在 attrs.xml 文件中添加名为 CircleView 的子项

<resources>
    <declare-styleable name="CircleView">
        <attr name="circle_color" format="color"/>
    </declare-styleable>
</resources>

2.在需要的地方如下调用:

@AttrRes
public int returnAttr() {
    return R.attr.circle_color;
}

如果将 return R.attr.circle_color; 改成 return 1; 或 return R.string.test; 等均会报错。

BinderThread

1.表明指定的元素只能运行在 Binder 线程:

@BinderThread
public void test() {
    // ...
}

BoolRes

1.在 values 文件夹下创建 bools.xml 文件

2.在 bools.xml 文件中添加名为 isHide 的子项

<resources>
    <bool name="isHide">true</bool>
</resources>

3.在需要的地方如下调用:

@BoolRes
public int returnBool() {
    return R.bool.isHide;
}

如果将 return R.bool.isHide; 改成 return 1; 或 return R.string.test; 等均会报错。

CallSuper

1.在 BaseActivity 中创建一个 init() 方法,我们在其中初始化一些 Activity 共有的初始化操作:

public class BaseActivity extends AppCompatActivity {
    // ...

    @CallSuper
    public void init() {
        // Activity 共有的初始化操作...
    }
}

2.在具体 Activity 中继承 BaseActivity 并调用 init() 完成初始化操作:

public class MainActivity extends BaseActivity {
    // ...

    @Override
    public void init() {
        // super.init();
    }
}

如果在 init() 方法中不通过 super.init() 等方式调用父类方法,那么就会报一个 warning,编译器将会建议你调用 super.init()

CheckResult

1.创建一个 add() 方法:

@CheckResult
public int add() {
    return 666;
}

2.调用该方法的地方不能忽略它的返回值:

add();  // error
int num = add();  // ok

ColorInt

ColorLong

ColorRes

1.在 colors.xml 下添加名为 colorAccent 的子项

<resources>
    <color name="colorAccent">#FF4081</color>
</resources>

2.在需要的地方如下调用:

@ColorRes
public int returnColorRes() {
    return R.color.colorAccent;
}

如果将 return R.color.colorAccent; 改成 return 1; 或 return R.string.test; 等均会报错。

DimenRes

1.在 dimens.xml 下添加名为 textview_height 的子项

<resources>
    <dimen name="textview_height">25dp</dimen>
</resources>

2.在需要的地方如下调用:

@DimenRes
public int returnDimenRes() {
    return R.dimen.textview_height;
}

如果将 return R.dimen.textview_height; 改成 return 1; 或 return R.string.test; 等均会报错。

Dimension

1.在需要的地方如下调用:

@Dimension(unit = Dimension.DP)
public int returnDimenRes() {
    return 666;
}

注:该注解仅表明希望该方法返回的是一个 DP 的值,而返回值本身和 DP 无关

DrawableRes

1..在 drawable.xml 文件中添加名为 btn_test 的子项

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_focused"
          android:state_window_focused="true"/>
    <item android:drawable="@drawable/btn_normal"/>
</selector>

3.在需要的地方如下调用:

@DrawableRes
public int returnDrawRes() {
    return R.drawable.btn_test;
}

如果将 return R.drawable.btn_test; 改成 return 1; 或 return R.string.test; 等均会报错。

FloatRange

1.用该注解所标记的元素只能返回指定范围内的浮点型数字,例如:

@FloatRange(from = -0.5F, to = 0.5F)
public float returnFloat() {
    // return 0.8F; // error
    return 0.2F;    // ok
}

FractionRes

同 ColorRes 等。

IdRes

同 ColorRes 等。

IntDef

1.用该注解修饰一个注解:

@IntDef({LAST, NOW, NEXT})
@Retention(RetentionPolicy.SOURCE)
public @interface Year {
    int LAST = 2016;
    int NOW = 2017;
    int NEXT = 2018;
}

2.再用被修饰的注解去注解指定元素:

@Year
public int returnYear() {
    // return 666; // warning
    return Year.LAST;   // ok
}

IntegerRes

同 BoolRes 等。

InterpolatorRes

同 ColorRes 等。

IntRange

FloatRange

Keep

1.对于不希望被混淆的代码我们使用该注解:

@Keep
public void test() {
    // ...
}

LayoutRes

同 ColorRes 等。

MainThread

同 BinderThread,表指定元素只能运行在主线程。

同 ColorRes 等。

NonNull

1.如果被注解的元素不可以取空值的话,我们使用该注解:

public Intent start2Activity(@NonNull String data) {
    Intent intent = new Intent(MainActivity.this, SecondActivity.class);
    intent.putExtra("DATA", data);

    return intent;
}

2.在调用该方法处如果我们传入 null 作为参数编译器将会给出 warning:

public void test() {
    start2Activity(null);  //warning,passing ‘null‘ argument to paramter annotated as @NonNull
}

Nullable

同 NonNull,意义相反,表被注解的元素可为空。

PluralsRes

同 BoolRes 等。

Px

实际等同于 Dimension 中 unit 取 PX 时的意义。

RawRes

同 BoolRes 等。

RequiresApi

1.当你使用的代码(例:API 11)不支持你当前所支持的最低版本(例:API 10)时,使用该注解注明:

@Override
protected void onCreate(Bundle savedInstanceState) {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

2.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 所支持最低版本为 API 11,如果你的项目最低兼容到11以下的版本,那么编译器将会给出 warning,解决方法有三:

  • 使用 RequiresApi 注解:

    @Override
    @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
    protected void onCreate(Bundle savedInstanceState) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    }
    
  • 使用 Target 注解:

    @Override
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
  • 使用 if 包裹相应代码块:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    

注:网上大篇文章提到使用 RequiresApi 或 Target 注解能够解决低版本兼容问题,实际上它只是作为一个对程序员的提醒,告诉程序员这块代码只有在指定版本及以上才能使用,而并不是也不能用来解决兼容问题,指定代码块在低于指定版本上是不会运行的!

RequiresPermission

1.表注解的元素需要相应的权限:

@RequiresPermission(Manifest.permission.INTERNET)
private void netOperation() {
}

2.如果你的项目没有在 AndroidMenifest.xml 中声明相应的权限,那么调用该方法的地方将会抛出 Missing permissions required by MainActivity.netOperation:android.permission.INTERNET warning,所以同样的,这个注解只是告诉程序员指定的元素需要某个权限,而不代表使用了该注解后就不需要注册权限。

RequiresPermission.Read

同 RequiresPermission

RequiresPermission.Write

同 RequiresPermission

RestrictTo

1.该注解用于想要指定访问元素权限的范围,例如我们在 BaseActivity 中对 init() 方法使用该注解:

@RestrictTo(RestrictTo.Scope.SUBCLASSES)
public void init() {

}

2.这是限定了该方法只能由 BaseActivity 子类才能访问到,如果是非子类访问,则会被编译器抛出 BaseActivity.int() can only be called from subclass warning。

注:除 RestrictTo.Scope.SUBCLASSES 之外,还有其它几种枚举类型,详情可自行查看源码

Size

1.常用于限定数组大小的场合:

public @Size(2) int[] returnArr() {
    int[] arr = new int[3];
    int[] array = new int[2];
    // return arr; // Size must be exactly 2.
    return array; // ok
}

StringDef

同 IntDef

StringRes

同 ColorRes 等。

StyleableRes

同 ColorRes 等。

StyleRes

同 ColorRes 等。

TransitionRes

同 ColorRes 等。

UiThread

同 BinderThread,表指定元素只能运行在 UI 线程。

WorkerThread

同 BinderThread,表指定元素只能运行在工作线程。

XmlRes

同 ColorRes 等。

SuppressLint

1.在想要屏蔽 Lint 静态检测工具的提示的地方添加该注解:

@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        // ...
    }
};

TargetApi

见 RequiresApi

 

============= End

 

Android 注解指南

上一篇:PC端访问移动站跳转PC站


下一篇:解决IOS新建工程删除main.storyboard程序黑屏的方法