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的一些知识总结,希望大家有所收获。

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

你可能感兴趣的:(Support Annotation Library总结)