Support Annotation Library总结

使用 Support Annotation Library

写在前面

    在看《Android高级进阶》一书看到注解那一章,发现看似不起眼的@后面其实隐藏的大学问。

    注解,相信我们程序猿不可能陌生,android有一个在api 19.1 上引入了一个全新的函数包里面全是我们熟悉又陌生的注解。熟练的使用这东西可以把你的代码可读性提高数倍。

注解的分类

    support-annotation-23.1.1函数包中,一共有39种注解,可以分为11类来跟大家说明一下。

Nullness注解

    很明显是表示能不能为空的注解,一般会用在参数或者返回值上,这种注解有:

    @Nullable //标记可以为空
    @NonNull  //标记不能为空

    如果有违反注解标记的代码的时候,Android Studio会给出提示,警告。

资源类型注解

    Android的资源通常是以整型值来表示是常识,并且会保存在R.java文件当中。然而会有一个问题,在编译的过程中如果我要一个R.layout.***的整型资源参数,我传入了一个String资源值也不会报错,直到我运行程序才会出现问题,报错。
所以为了防止这种这么降低效率的情况出现,我们很有必要需要资源注解来声明我们到底需要的是什么资源。

注解 作用
AnimationRes 标记整型值是 android.R.animator 类型
AnimRes 标记整型值是 android.R.anim 类型
AnyRes 标记为整型值是任意资源
ArrayRes 标记整型值是android.R.array类型
AttrRes 标记整型值是android.R.attr类型
BoolRes 标记整型值是布尔类型
ColorRes 标记整型值是android.R.color类型
DrawableRes 标记整型值是android.R.drawable类型
FractionRes 一般在动画xml文件中使用,如:50%p 表示占parent 50%
IdRes 标记整型值是anroid.R.id类型
IntegerRes 标记整型值是anroid.R.integer类型
InterpolatorRes 标记整型值是android.R.interpolator类型
LayoutRes 标记整型值是android.R.layout类型
MenuRes 标记整型值是android.R.menu类型
PluralsRes 标记整型值是android.R.plurals类型
RawRes 标记整型值是android.R.raw类型
StringRes 标记整型值是android.R.string类型
StyleableRes 标记整型值是android.R.styleable类型
StyleRes 标记整型值是android.R.style类型
TransitionRes 标记整型值是android.R.transition类型
XmlRes 标记整型值是android.R.xml类型

  所有资源注解都一样情况,如果输入的资源参数跟注解的相违反,那么Android Studio就会检查出来然后报错。

类型定义注解

  使用这一类注解我们可以创建一个自己的新注解,并可以使用这个新注解来标记自己的API,比如@IntDef的用法,我们可以看看ActionBar里面是怎么用它的

   import android.support.annotation.InDef;
   ...
   public abstract class ActionBar{
       
       //跟编译器声明不需要在.class文件中存储注解数据
       @Retention(RetentionPolicy.SOURCE)
       
       //定义可以接受的常量列表
       @IntDef({NAVIGATION_MODE_STANDARD,NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
       
       //定义NagavitionMode 注解
       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;

       //使用NagavitionMode注解
       @NavigationMode
       ...
       public abstract void setNagavitionMode(@NagavitionMode int mode);
   }

    在使用setNagavitionMode这个方法的时候,我们传的参数mode要是不是定义的三个常量之一时,Android Studio就会发出警告。

    一般使用这类注解,我们会把它当作枚举的代替品,而且它比枚举更加的易懂,方便。

线程注解

线程注解有四种 :

  • @UiThread:标记运行在UI线程。
  • @MainThread:基本同UiThread的用法一样,不过一般MianThread会注解生命周期相关函数。
  • @WorkThread:标记运行在后台的线程。
  • @BinderThread:标记运行在Binder的线程。

以AsyncTask的实现为例子:

    @MainTread
    protected void onPreExecute(){}

    @WorkerThread
    protected adstract Result doInBackground(Params...params);

    @MainThread
    protected void onProgressUpdate(Progress...values){}; 

RGB颜色值的注解

    这个跟 @ColorRes 不太一样,@ColorInt标记的是一个代表颜色的RGB值,用法例如TextView源码里面:

    public void setTextColor(@ColorInt int color){
        ...
    }

值范围注解

    标记参数的取值范围,防止传入错误的参数。声明范围的注解有三种:

  1. @Size:主要声明的对象是数组,集合,字符串等参数,用来声明它们的长度范围,用法如下:
    @Size(min =1) //可以表是集合不能为空

    @Size(max = 23) //可以表示字符串最大字符个数是23

    @Size(2) //可以表示数组的元素为2个

    @Size(multiple = 2) //可以表示数组大小为2的倍数
  1. @IntRange:主要声明对象是int跟long,用法如下:
    public void setAlpha(@IntRange(from = 0 ,to = 255) int alpha){...}
  1. @FloatRange:主要声明对象是float或者double,用法如下:
    public void setAlpha(@FloatRange(from = 0.0,to =1.0)){...}

权限注解

    android 的权限管理一直是令人又爱又恨的东西,我们需要在AndroidManifest.Xml文件里面声明权限,不然我们无法使用该权限去运行某些功能,为了能在编译的时候就能及时发现缺失的权限,我们可以使用@RequiresPermission注解。

  • 如果函数调用需要声明一个权限,语句如下:
    @RequiresPermission(Manifest.permission.SET_WALLPAPER)
    public abstract void setWallpaper(Bitmap bitmap)throws IOException;
  • 如果函数调用需要声明集合中至少一个权限,语句如下:
    @RequiresPermission(anyOf = {Mainfest.permission.ACCESS_COARSE_LOCATION,Mainfest.permission.ACCESS_FINE_LOCATION})
    public abstract Location getLastKnownLocation(String provider);
  • 如果函数调用需要声明多个权限,语句如下:
    @RequiresPermission(allOf = {Mainfest.permission.ACCESS_COARSE_LOCATION,Mainfest.permission.ACCESS_FINE_LOCATION})
    public abstract Location getLastKnownLocation(String provider);
  • 对于Intent调用所需权限,可以在Intent的ACTION字符串定义处添加注解,语句如下:
     @RequiresPermission(android.Mainfest.permission.BLUETOOTH)
     public static final String ACTION_REQEST_DISCOVERABLE ="android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
  • 对于ContentProvider相关所需的权限,可能同时需要读和写这两个操作,对应不同的权限声明,语句如下。
    @RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
    @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
    public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");

重写函数注解

    @CallSuper 这是一个用在可能需要被重写的方法上的,提示开发者重写该方法需要回调父类的同一方法。示例如下:

    @CallSuper
    protected void onCreate(@Nullable Bundle savedInstanceState);

注解返回值

在编写函数的时候我们需要调用者对函数的返回值进行处理,那么可以用@CheckResult注解来提示开发者。Android源码的Context类为例:

    @CheckResult(suggest="#enforcePermission(String,int,int,String)")
    @PackageManager.PermissionResult
    public abstract int checkPermission(@NonNull String permission,int pid,int uid);

    如果调用者没有检查返回值,Android Studio 会给出警告,内容为suggest里面的内容。

测试可见注解

    测试的过程中我们会访问一些不可见的类,变量还有函数,使用@VisibleForTesting可以让它们变得测试可见。

标记非混淆注解

    @Keep用来注解代码混淆过程中不需要混淆的部分。使用方法:

    public class AnnotationDemo{
        @Keep
        public void doSomething(){
            //....
        }
        //...
    }

注解的去向

    如果项目打包成aar压缩包,注解信息会被抽离出来放在aar文件的annotation.zip中。

写在后面

    以上是对Support Annotation Library的一些知识总结,希望大家有所收获。

    讲道理,这么多种类的注解,要是灵活的运用在团队的项目开发中,妈妈再也不用担心别人读不懂我的代码了。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,116评论 25 707
  • 这是篇笔记。转自于 http://blog.csdn.net/sw5131899也对其中的错误进行了一些更正。 S...
    wenld_阅读 1,667评论 0 2
  • 赶一趟风雨的闹市 一 一团火从地底下喷出, 风一下子把它撕成粉末。 碎片飘零…… 在时间的定位中, 这场面 有人说...
    西风剪剪阅读 192评论 1 0
  • 味道 今天我要说的味道,它不属榴莲的酸,蜜汁的甜,杏仁的苦,泰椒的辣,海水的咸,它不是酸甜苦辣咸五味中的...
    瓶水之冰阅读 486评论 0 0
  • 注:要查看mongodb的版本,不然使用db.collection()这个方法时会从mongodb的库中报这个错:...
    tree_book阅读 341评论 0 1