如果你是一名安卓开发者,你也一定听过大名鼎鼎的网络请求框架Retrofit。它将网络请求的方式以注解的形式展现,极大的提高了代码的可读性,同时网络请求集中写在一个interface中提高了代码的可维护性。除此之外,例如Dagger , GreenDao,ButterKnife等等 也是大量运营了注解。为什么这些知名的开源项目如此青睐注解?

在注解使用之前,xml被广泛用于描述原数据,但是在使用xml越来越长之后,开发人员意识到使用xml耦合性太高。于是在java 5.0 的版本,注解(Annotation)出现了。目前xml 与 Annotation 共同使用着,发挥着他们的长处。我们该如何使用注解呢?其实注解使用起来非常简单。一个自定义注解可以被四个java 规定的原注解所描述这四个原注解分别是:@Documented   @Retention  @Target  @Inherited 。

@Documented -表示是否将注解信息添加在java文档中。

@Retention -定义该注解的生命周期。

RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。

 RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。

 RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

@Target -表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,

仅仅排除一个属性,那么你需要在定义target包含所有的属性。

ElementType.TYPE:用于描述类、接口或enum声明
 ElementType.FIELD:用于描述实例变量
 ElementType.METHOD
 ElementType.PARAMETER
 ElementType.CONSTRUCTOR
 ElementType.LOCAL_VARIABLE
 ElementType.ANNOTATION_TYPE 另一个注释
 ElementType.PACKAGE 用于记录java文件的package信息

@Inherited  -定义该注释和子类的关系

话不多说我们来实战一下。在我们开始写项目的时候通常都会封装一个BaseActivity,每个面向界面的Activity中都会指向一个xml 界面文件,也就是Activity 与 xml是绑定关系的。这样我们的注解就能派上用场了,我们可以通过注解将xml 绑定到对应的Activity中。一个Activity类中绑定一个layout 那么我们的注解描述类型就是TYPE。这个绑定效果一定是作用到运行时的,所以有了如下代码。

 @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface BindLayout {
@LayoutRes
int value(); }

我们通过反射获取到这个注解中传入的xml数据,将他绑定在Activity中。代码如下:

 private static void bindActivityLayout(Activity activity) {
Class aClass = activity.getClass();
BindLayout annotation = (BindLayout) aClass.getAnnotation(BindLayout.class);
if (annotation != null) {
activity.setContentView(annotation.value());
ButterKnife.bind(activity);
}
}

我们只要在Activity中的OnCreate初始化一下,就能够轻松实现绑定。

@BindLayout(R.layout.activity_xx)
public class XXActivity extends Activity { @Override
protected void onCreate() {
MoBind moBind = new MoBind();
moBind.bindActivity(this); }
... }

比较正确的做法是将绑定方法放入BaseActivity中,让我们的子类继承于他,这样一对一的关系变的简洁明了。当然,不只只是这样,你可以开发新的用途,例如,我们需要在界面中绑定其他View做一下操作,比如显示一个空的界面或者显示一个自定义的Dialog。

通过注解,也可以快速的绑定,还记得我们的原注解Targe可以修饰一个变量,于是绑定一个其他View在Activity中就可以这么做:

 @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface BindOthersView {
@LayoutRes int value();
}

我们一样通过反射调用:

 private static void bindActivityView(Activity activity) {
Field[] declaredFields = activity.getClass().getDeclaredFields();
if (declaredFields != null && declaredFields.length > 0) {
for (Field f : declaredFields) {
BindOthersView annotation = f.getAnnotation(BindOthersView.class);
if (annotation != null) {
View inflate = LayoutInflater.from(activity).inflate(annotation.value(), null);
if (inflate != null) {
try {
f.setAccessible(true);
f.set(activity, inflate);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
} }

我们只需要在BaseActivity中的OnCreate 中初始化一次,就可以在它的子类中随意绑定其他View(代码中已经做了初始化,请放心使用)。

@BindOthersView(R.layout.empty_view)

View emptyView;

怎么样,实现起来是不是非常简单,总结起来就是三个步骤,定义注解,解析注解,使用注解。快去定义你自己的注解,让你的代码变得简洁且逼格满满吧。

Android中注解的使用的更多相关文章

  1. Android中通过注解代替findViewById方法

    转自:http://www.2cto.com/kf/201405/302998.html 这篇文章主要讲解注解实现findViewById的功能,首先我们来熟悉一下在java中怎么定义一个注解和解析一 ...

  2. 注解在android中的使用

    注解在android程序中的使用 何为注解: 在Java其中,注解又叫做"元数据",它为我们在源码中加入信息提供了一种形式化的方法.让我们能在以后的某个时间方便的使用这些数据.更确 ...

  3. 在Android中使用枚举注解而不是枚举

    Enums often require more than twice as much memory as static constants. You should strictly avoid us ...

  4. android 中的一些资源注解,让编译器帮你检查代码

    android 中的一些资源注解,让编译器帮你检查代码 写方便的时候可以用注解来声明一些参数,以明确的指示参数的类型,让代码更安全.我们看到,在android源代码里大量使用了注解.我整理了一些注解如 ...

  5. 理解Android中的注解与反射

    反射 Java反射(Reflection)定义 Java反射机制是指在运行状态中 对于任意一个类,都能知道这个类的所有属性和方法:对于任何一个对象,都能够调用它的任何一个方法和属性: 这样动态获取新的 ...

  6. Android中使用ViewPager实现屏幕页面切换和页面切换效果

    之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpag ...

  7. Android中Retrifit使用总结

    Android中网络请求框架Retrofit的使用注意事项 1.Retrofit是基于OkHttp网络请求框架的二次封装而已,懂Okhttp的小伙伴,那么Retrofit也就基本都会. 2.Retro ...

  8. Android中的Touch事件

    Android中的Touch事件处理 主要内容 Activity或View类的onTouchEvent()回调函数会接收到touch事件. 一个完整的手势是从ACTION_DOWN开始,到ACTION ...

  9. Android 进阶 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

随机推荐

  1. SpringCloud统一配置之使用配置

    配置的读取方式在上一篇文章中有提到. 取到值之后赋值给静态类里的静态变量. 因为SpringCloud项目启动的时候会把所有的api都执行一遍(相当蛋疼),所以这里直接就可以写一个方法进行赋值. 代码 ...

  2. MessageFormat用法(转载)

    MessageFormat用来格式化一个消息,通常是一个字符串,比如: String str = "I'm not a {0}, age is {1,number,short}", ...

  3. C# webbrowser实现百度知道团队邀请助手!

    [百度知道团队邀请助手] 是您快速提高百度知道团队成员数和团队排名的利器! 主要功能: 1.运用C#自带的webbrowser自动登录百度: 2.自动采集请在C#.Net分类排名下的所有用户,邀请这些 ...

  4. SDL播放音频的时候发现SDL_OpenAudioDevice打开一直失败

    1:在使用SDL播放音频的时候发现SDL_OpenAudioDevice打开一直失败,导致SDL不能进入回调函数. 使用SDL_GetError()打印错误提示XAudio2: XAudio2Crea ...

  5. Hive基础之排序

    order by 1.order by会对输入按照指定字段做全局排序,输出结果有序,因此只有一个reducer(多个reducer无法保证全局排序,手工设定reduce数量无效): 只有一个reduc ...

  6. fio与dd测试结果记录

    以下测试基于win7内安装的vbox虚机内进行. vbox-vm挂载了7.2k disk作为本地系统盘,挂载了ssd 8G空间作为mount /mnt/data /dev/sdb 今天顺便了做个一个简 ...

  7. CSS3基础知识(一)

    结构选择器 :nth-child(n) 第几个元素 从1开始设置 :nth-child(2n) 偶数元素 从0开始设置 :nth-child(2n+1) 奇数元素 :nth-of-type(n) :f ...

  8. mysq更新(六) 单表查询 多表查询

      本节重点: 单表查询 语法: 一.单表查询的语法 SELECT 字段1,字段2... FROM 表名 WHERE 条件 GROUP BY field HAVING 筛选 ORDER BY fiel ...

  9. 代码生成器 CodeSmith 的使用(二)

    在第一篇中,简单的介绍了 CodeSmith 的使用方法,这次做一个生成简单的数据库字段属性的模板.以下只粘贴主要的代码片段. <%-- Name: Copyright © Sun 2013-2 ...

  10. POI 解析excel 空行问题

    https://www.cnblogs.com/interdrp/p/4019583.html