Android进阶系列之Support Annotation Library使用详解

这是篇笔记。转自于 http://blog.csdn.net/sw5131899
也对其中的错误进行了一些更正。


Support Annotation Library是从Android Support Library 19.1开始引入的一个全新的函数包,它包含一系列有用的元注解,用来帮助开发者在编译期间发现可能存在的bug。

Support Library本身也使用Annotation Library 提供的注解来完善自身的代码质量,Android Studio 提供可视化的交互以便开发者发现问题。

Android Support Library 发展到现在已经不止是一个jar包了,而是拆分成多个独立的Jar包,例如support-v4、support-v7、gridlayout-v7、design、cardview-v7等等。

而Annotation Libary 也是其中之一,默认情况下是不会包含在工程中的,如果我们的SDK已经安装了Android Support Repository,那么我们打开Project Structure 对话框,并选中一个Module,选中Dependencies选项,点击“+”按钮,在弹出的Choose Library Dependency 对话框中轻松找到Annotation Library。

Nullness

  • @Nullable作用于函数参数或返回值,标记参数或返回值为可以空
  • @NonNull作用于函数参数或返回值,标记参数或返回值为不能为空

如果在函数参数或返回值使用了上述注解,而又出现违反该注解的代码时,Android Studio 会给出提示,同时使用Android Lint进行静态代码扫描,也会显示出错提示。

至于Android Lint使用请查看:
http://blog.csdn.net/sw5131899/article/details/53908776

具体使用如下图:


在Proable bugs中,我们可以看到程序可能发生bug的地方,这对于程序猿来说是神器啊,提前预知Bug在何处,提前避开bug。

资源类型注解

我们知道,资源是以int整型表示,并保存在R.Java文件中。这就意味着在一个需要Layout资源值函数传入String字符串,在编译时不会报错,只有在运行时才会报错,为了防止这种情况的出现,可以使用资源类型注解。

资源类型的注解作用于函数参数、返回值及类的变量,每种资源类型对应一种注解。

  • AnimatorRes:标记整型值是Android.R.animation类型。
  • AnimRes:标记整型是android.R.anim类型。
  • AnyRes:标记整型是任何一种资源类型,如果确切知道表示的是哪一个具体资源的话,建议显式指定。
  • ArrayRes:标记整型是android.R.array类型。
  • AttrRes:标记整型是android.R.attr类型。
  • BoolRes:标记整型是布尔类型。
  • ColorRes:标记整型是android.R.color类型。
  • DrawableRes:标记整型是android.R.drawable类型。
  • FranctionRes:标记整型值是fraction类型,这个比较少见,这种类型资源常见于Animation Xml中,比如50%,表示占parent的50%
  • IdRes:标记整型是android.R.id类型。
  • IntegerRes:标记整型是android.R.integer类型。
  • InterpolatorRes:标记整型是android.R.interpolator类型,插值器,在Animation Xml中使用较多。
  • LayoutRes:标记整型是android.R.layout类型。
  • MenuRes:标记整型是android.R.menu类型。
  • RawRes:标记整型是android.R.raw类型。
  • StringRes:标记整型是android.R.string类型。
  • StyleableRes:标记整型是android.R.styleable类型。
  • StyleRes:标记整型是android.R.style类型。
  • XmlRes:标记整型是android.R.xml类型。

类型定义注解

在Android开发中,整型值不止经常用来代表资源引用值,而且经常用来代替枚举值。@IntDef注解用来创建一个整型类型定义的新注解,我们可以使用这个新注解来标记自己编译的API。

先看看@IntDef的源码。就明白怎么回事了。


这里面可以定义一个布尔值,还可以定义多个long类型的值。那么就以long数组举例。

这里给TestAnnotation注解加上了@IntDef,这样在使用TestAnnotation的时候必须传入指定参数,若是非法在编译时就会报异常。

使用就非常简单了,找个类继承抽象类,实现方法。在调用的时候,只能传入指定的TEST_1,TEST_2,TEST_3。这样就可以自定义资源类型注解。非常方便。

线程注解

Android应用开发过程中,经常会涉及到多种线程的使用,界面相关操作必须在主线程,而耗时操作如文件下载等必须在后台线程中,线程注解相关有四种。

  1. @UiThread:标记运行在UI线程,一个UI线程是Activity运行所在的主窗口,对于一个应用而言,可能存在多个UI线程。每个UI线程对应不同的主窗口。
  2. @MainThread:标记运行在主线程,一个应用只有一个主线程,主线程也是@UiThread线程。通常情况下,我们使用@MainThread来注解生命周期相关函数,使用@UiThread来注解视图相关函数,一般情况下@MianThread和@UiThraed是可以互换的。
  3. @WorkerThread:标记运行在后台运行线程。
  4. @BinderThread:标记运行在Binder线程。

看个例子:

public void threadtest(){  
        new Thread(new TimerTask() {  
            @Override  
            public void run() {  
                setTest();  
            }  
        }).start();  
    }  
  
    @UiThread  
    public void setTest(){  
        test.setText("测试");  
    }

那么上面会报错。
提示:不做线程切换,只起到提示作用!

RGB颜色值注解

在资源类型注解中我们使用@ColorRes来标记参数类型需要传入颜色类型的id,而使用@ColorInt注解是标记参数类型需要传入RGB

或者ARGB颜色值的整型值。

在TextView的源码中可以找到如下例子。

public void setTestColor(@ColorInt int color){  
        mTextColor = ColorStateList.valueOf(color);  
        updateTextViewColors();  
    }

值范围注解

当函数参数的取值在一定范围时,可以使用注解来防止调用者传入错误的参数,主要注解有三种。

  1. @Size:对于类似数组、集合和字符串之类的参数,我们可以使用@Size注解来表示这些参数的大小。用法:
    @Size(min=1)//可以表示集合不可以为空
    @Size(max=23)//可以表示字符串最大字符个数为23
    @Size(2)//表示数组元素个数为2个
    @Size(multiple=2)//可以表示数组大小是2的倍数
  2. @IntRange:参数类型是int或者long,用法如下
public void setInt(@intRange(from=0,to=255)){...}
  1. @FloatRange:参数类型是float或者double,用法如下。
public void setFloat(@FloatRange(from=0.0,to=1.0)){...}

权限注解

Android应用在使用某些系统功能时,需要在AndroidManifest,xml中声明权限,否则在运行时就会提示缺失对应的权限,为了在编译时及时发现权限的缺失,我们可以使用

@RequiresPermission注解。

  1. 如果需要一个权限则加注解。
    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
  2. 如果需要一个集合至少一个权限,那么就加注解。
    @RequiresPermission(anyOf = {Manifest.permission.SET_WALLPAPER,Manifest.permission.CAMERA})
  3. 如果同时需要多个权限,那么就加注解。
{Manifest.permission.SET_WALLPAPER,Manifest.permission.CAMERA})```
4. 对于Intent调用所需权限的ACTION字符串定义处添加注解。

@RequiresPermission(android.Manifest.permission.BLUETOOTH)
String ACTION_REQUEST_DISCOVERRAVLE = "android.bluetooth.adapter.REQUEST_DISCOVERRAVLE";

5. 对于ContentProvider所需权限,可能有读和写两个操作。对应不同的权限。

@RequiresPermission.Read(@RequestPermission(READ_HISTORY_BOOLMARKS))
@RequiresPermission.Write(@RequestPermission(WRITE_HISTORY_BOOLMARKS))
public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks);


###重写函数注解
如果API允许重写某个函数,但是要求在重写该函数时需要调用super父类的函数。

可以加注解@CallSuper来提示开发者。testCallSuper方法我加了注解,若是重写不调用super就会报错


![](http://upload-images.jianshu.io/upload_images/1599843-efe0f923a61e8324.png)


子类在重写testCallSuper方法时,必须调用super.testCallSuper();

###@Keep注解
@keep是用来标记在Proguard混淆过程中不需要混淆的类或者方法。在混淆时一些不需要混淆的会使用

-keep class com.foo.bar{public static <method>}

有了@Keep之后,就可以在编码时标注出一些不需要混淆的类或者方法、


### @SuppressWarnings注解
这个注解在源码里是随处可见,其实它的用法很简单,就是对一些警告信息的过滤。那么怎么使用呢,我们来看看它的源码。

![](http://upload-images.jianshu.io/upload_images/1599843-ed32a3718bd43a5e.png)

这个注解是可以使用在属性、方法、构造方法、变量等等。那么它的参数就是一个字符串数组。可以单个,可以多个。

那么字符串有哪些呢。根据sun的官方文档描述:

> value - 将由编译器在注释的元素中取消显示的警告集。允许使用重复的名称。忽略第二个和后面出现的名称。出现未被识别的警告名不是 错误:编译器必须忽略无法识别的所有警告名。但如果某个注释包含未被识别的警告名,那么编译器可以随意发出一个警告。各编译器供应商应该将它们所支持的警告名连同注释类型一起记录。鼓励各供应商之间相互合作,确保在多个编译器中使用相同的名称。

示例:
-  `@SuppressWarnings("unchecked")`
告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
-   `@SuppressWarnings("serial")`
如果编译器出现这样的警告信息:The serializable class WmailCalendar does not declare a static final serialVersionUID field of type long
       使用这个注释将警告信息去掉。
-   `@SuppressWarnings("deprecation")`
如果使用了使用@Deprecated注释的方法,编译器将出现警告信息。
       使用这个注释将警告信息去掉。
-    `@SuppressWarnings("unchecked", "deprecation")`
告诉编译器同时忽略unchecked和deprecation的警告信息。
-   ` @SuppressWarnings(value={"unchecked", "deprecation"})`
等同于@SuppressWarnings("unchecked", "deprecation")

到这里注解玩的差不多了。那么就开始运用到项目中提高自己编码的质量吧。

这里是官网API地址 https://developer.android.com/reference/android/support/annotation/AnimatorRes.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容