2843
- 收藏
- 点赞
- 分享
- 举报
安卓注解那些事儿
本帖最后由 jp1017 于 2015-10-14 19:01 编辑
博客: [[url=http://jp1017.gitcafe.io/]安卓之家[/url]]
微博: [[url=http://weibo.com/1321395433/profile?topnav=1&wvr=6]追风917[/url]]
CSDN: [[url=http://blog.csdn.net/u010331406]蒋朋的家[/url]]
简书: [[url=http://www.jianshu.com/users/8cb49b5ad78b/latest_articles]追风917[/url]]
博客园: [url=http://www.cnblogs.com/jp1017/][追风917[/url]]
木有markdown,没法在这里玩了
Annotation
Annotation就是注解了,JDK1.5新增加功能,该功能可用于类,构造方法,成员变量,方法,参数等的声明中,比如常见的@Override,butterknife库里的@Bind, 该功能并不影响程序的运行,但是会对编译器警告等辅助工具产生影响。
关于java注解的详细介绍,包括概念,作用,分类,解析及几个常用的安卓库的原理解析等请来这里查看[url=http://www.trinea.cn/android/java-annotation-android-open-source-analysis/]:[Java Annotation 及几个常用开源项目注解原理简析]
[/url]
Android Annotation
Android Annotation是以Support Library的形式给我们提供的,从安卓19.1开始出现,该包在sdk目录\Sdk\extras\android\m2repository\com\android\support\support-annotations下:

api版本23下,android studio里是直接可以使用的,不用添加依赖库,以前的api可能需要,请酌情增删。api23暂时有39个注解,可以这里查看:

安卓注解有8种类型,分别是Nullness注解、资源类型注解、线程注解、变量限制注解、权限注解、结果检查注解、CallSuper注解、枚举注解(IntDef和StringDef)。
下面简单摘录几个,以飨读者:
Nullness注解
包括@NoNull和@Nullable,这里以@NoNull为例说明:
先看下@NoNull的源码:
```java
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface NonNull {
}
```
这里我们知道,@NoNull编译到类文件里,应用于方法,参数和成员变量,下面我们先来一发:
```java
public class MainActivity extends Activity {
@NonNull private String str;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
str = null;
}
}
```
我们给成员变量str加上了@NoNull注解,也就是str不能为null,而后面我们把str初始化为null,此时as编译器这样提示我们:

也就是str不能为空,这就像是一种约定,很像c语言里的断言assert。这样有什么好处呢?这样可以避免后面的频繁判断str是否为空的操作,如果和别的项目配合呢,可能会出现某些bug,而使用注解可以很好的用于团队合作,项目维护起来也方便。
资源类型注解
此类注解以Res结尾,比如@BoolRes, @IdRes, @IntegerRes, @StringRes, @ColorRes等,这里以@ColorRes为例说明
先看下@ColorRes的源码:
```java
@Documented
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface ColorRes {
}
```
这里我们知道,@ColorRes在编译时生效,使用于方法,参数和成员变量和局部变量,下面我们再来一发:
```java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getCurColor(R.id.ic_launcher);
}
void getCurColor(@ColorRes int color) {
Toast.makeText(this, "Color: " + getString(color), Toast.LENGTH_LONG).show();
}
}
```
我们给getColor函数的参数color加上了@ColorRes注解,即该参数是一个颜色资源,而上面我们上面传递的是id资源,此时as编译器这样提示我们:

我们这样调用就ok的
```java
getCurColor(R.color.material_blue_grey_900);
```
:看到了吧,好玩吗?
:嗯,as很好很强大,,,
:好的,我们继续。
权限注解
直接上代码了,源码自己查阅咯
```java
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;
```
此例说明setWallpaper方法有设置壁纸的权限。
CallSuper Annotations
直接来了哈,我们看Activity.java源码里的onCreate方法
```java
@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}
```
@CallSuper说明所有重写onCreate()方法的方法都要有super.onCreate();
枚举注解
有时候,基于性能的考虑,需要用整型常量代替枚举类型,此时枚举注解可以轻松搞掂,这就是大名鼎鼎的@IntDef and @StringDef,我们看看@IntDef源码
```java
@Retention(Source)
@Target({ANNOTATION_TYPE})
public @interface IntRef {
long[] value() default {};
boolean flag() default false;
}
```
可见该注解表示不编译annotation到类文件中,用于注解类型,再来一发?好的,我们看看ActionBar源码吧:
```java
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);
```
我们来看,请忽略注释信息,前三句是一句话,新建了一个@NavigationMode注解,并使用@IntDef指定它可以接受的值类型。当使用setNavigationMode方法时,as会提示需要的参数,当然如果你写错的话,as会报错哦,so,as是一个神器。
当然@IntDef还可以定义标志位,详细说明请移步[url=https://developer.android.com/intl/zh-cn/tools/debugging/annotations.html#call-super][Improving Code Inspection with Annotations]
[/url]
好了,这里抛砖引玉,简单介绍了安卓注解,我们可以看到安卓源码里大量应用这个技巧,大家也要用起来哦,还可以来这里深入学习:
[url]http://tools.android.com/tech-docs/support-annotations[/url]
enjoy!
悦分享,越快乐^_^
欢迎交流,转载请注明出处,谢谢![postbg]bg3.png[/postbg]
博客: [[url=http://jp1017.gitcafe.io/]安卓之家[/url]]
微博: [[url=http://weibo.com/1321395433/profile?topnav=1&wvr=6]追风917[/url]]
CSDN: [[url=http://blog.csdn.net/u010331406]蒋朋的家[/url]]
简书: [[url=http://www.jianshu.com/users/8cb49b5ad78b/latest_articles]追风917[/url]]
博客园: [url=http://www.cnblogs.com/jp1017/][追风917[/url]]
木有markdown,没法在这里玩了
Annotation
Annotation就是注解了,JDK1.5新增加功能,该功能可用于类,构造方法,成员变量,方法,参数等的声明中,比如常见的@Override,butterknife库里的@Bind, 该功能并不影响程序的运行,但是会对编译器警告等辅助工具产生影响。
关于java注解的详细介绍,包括概念,作用,分类,解析及几个常用的安卓库的原理解析等请来这里查看[url=http://www.trinea.cn/android/java-annotation-android-open-source-analysis/]:[Java Annotation 及几个常用开源项目注解原理简析]
[/url]
Android Annotation
Android Annotation是以Support Library的形式给我们提供的,从安卓19.1开始出现,该包在sdk目录\Sdk\extras\android\m2repository\com\android\support\support-annotations下:

api版本23下,android studio里是直接可以使用的,不用添加依赖库,以前的api可能需要,请酌情增删。api23暂时有39个注解,可以这里查看:

安卓注解有8种类型,分别是Nullness注解、资源类型注解、线程注解、变量限制注解、权限注解、结果检查注解、CallSuper注解、枚举注解(IntDef和StringDef)。
下面简单摘录几个,以飨读者:
Nullness注解
包括@NoNull和@Nullable,这里以@NoNull为例说明:
先看下@NoNull的源码:
```java
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface NonNull {
}
```
这里我们知道,@NoNull编译到类文件里,应用于方法,参数和成员变量,下面我们先来一发:
```java
public class MainActivity extends Activity {
@NonNull private String str;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
str = null;
}
}
```
我们给成员变量str加上了@NoNull注解,也就是str不能为null,而后面我们把str初始化为null,此时as编译器这样提示我们:

也就是str不能为空,这就像是一种约定,很像c语言里的断言assert。这样有什么好处呢?这样可以避免后面的频繁判断str是否为空的操作,如果和别的项目配合呢,可能会出现某些bug,而使用注解可以很好的用于团队合作,项目维护起来也方便。
资源类型注解
此类注解以Res结尾,比如@BoolRes, @IdRes, @IntegerRes, @StringRes, @ColorRes等,这里以@ColorRes为例说明
先看下@ColorRes的源码:
```java
@Documented
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
public @interface ColorRes {
}
```
这里我们知道,@ColorRes在编译时生效,使用于方法,参数和成员变量和局部变量,下面我们再来一发:
```java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getCurColor(R.id.ic_launcher);
}
void getCurColor(@ColorRes int color) {
Toast.makeText(this, "Color: " + getString(color), Toast.LENGTH_LONG).show();
}
}
```
我们给getColor函数的参数color加上了@ColorRes注解,即该参数是一个颜色资源,而上面我们上面传递的是id资源,此时as编译器这样提示我们:

我们这样调用就ok的
```java
getCurColor(R.color.material_blue_grey_900);
```
:看到了吧,好玩吗?
:嗯,as很好很强大,,,
:好的,我们继续。
权限注解
直接上代码了,源码自己查阅咯
```java
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public abstract void setWallpaper(Bitmap bitmap) throws IOException;
```
此例说明setWallpaper方法有设置壁纸的权限。
CallSuper Annotations
直接来了哈,我们看Activity.java源码里的onCreate方法
```java
@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}
```
@CallSuper说明所有重写onCreate()方法的方法都要有super.onCreate();
枚举注解
有时候,基于性能的考虑,需要用整型常量代替枚举类型,此时枚举注解可以轻松搞掂,这就是大名鼎鼎的@IntDef and @StringDef,我们看看@IntDef源码
```java
@Retention(Source)
@Target({ANNOTATION_TYPE})
public @interface IntRef {
long[] value() default {};
boolean flag() default false;
}
```
可见该注解表示不编译annotation到类文件中,用于注解类型,再来一发?好的,我们看看ActionBar源码吧:
```java
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);
```
我们来看,请忽略注释信息,前三句是一句话,新建了一个@NavigationMode注解,并使用@IntDef指定它可以接受的值类型。当使用setNavigationMode方法时,as会提示需要的参数,当然如果你写错的话,as会报错哦,so,as是一个神器。
当然@IntDef还可以定义标志位,详细说明请移步[url=https://developer.android.com/intl/zh-cn/tools/debugging/annotations.html#call-super][Improving Code Inspection with Annotations]
[/url]
好了,这里抛砖引玉,简单介绍了安卓注解,我们可以看到安卓源码里大量应用这个技巧,大家也要用起来哦,还可以来这里深入学习:
[url]http://tools.android.com/tech-docs/support-annotations[/url]
enjoy!
悦分享,越快乐^_^
欢迎交流,转载请注明出处,谢谢![postbg]bg3.png[/postbg]
我来回答
回答4个
时间排序
认可量排序
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片
相关问答
-
2020-04-17 16:24:01
-
32015-08-17 20:38:04
-
2015-08-07 21:22:46
-
2015-08-19 21:45:26
-
12015-08-17 21:09:26
-
2015-08-31 10:02:50
-
2015-08-05 14:51:39
-
2015-08-17 20:11:57
-
2019-01-13 11:15:59
-
2015-08-17 19:45:57
-
2015-08-05 18:05:47
-
2020-07-07 17:58:02
-
2015-08-04 20:13:23
-
2015-12-09 13:18:28
-
2016-07-18 15:12:22
-
2019-12-05 16:21:34
-
2015-08-21 16:53:44
-
2015-08-09 20:39:38
-
2019-01-15 16:16:26
无更多相似问答 去提问

点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认