@interface 在Android开发中的使用

@interface 在Android开发中的使用

该文章转自:http://blog.sina.com.cn/s/blog_4e1e357d0101abda.html
引子:java  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。
在使用 360 桌面一键清理内存,或者点击手机 HOME 键前后台切换时,是有可能将 Android 手机的一些权值较低的 ACTIVITY“kill”
但这种 KILL 不是真的 KILL,Android OS  会把 activity 的内容清掉(可以理解为 context , 然后在下次起动这个 activity (长按 home 键进入)时,根据上次 "KILL" 时候,系统保存的一些 activity 引用信息,重新启动一个全新的 activity, 所以会重新调用 onCreate ()方法。
onCreate()方法中一般默认有一句, super.onCreate(savedInstanceState);
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

  如果是正常的A,B两个activity进行startActivity()进行切换时, savedInstanceState这变量实际是nulL,的所以一种比较优雅的做法是。在项目中将所有的Activity继承于一个统一的BaseActivity,然后在BaseActivity中@override  onSaveInstanceState(){}方法,通过注解@Annotation去  在真正的业务Activity中去把需要用到的全局,和本Activity中的可能被非正常变量进行声明。
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SaveWithActivity {
}
根据googleactivity的生命周期文档,实际发生作用的效果是:在activity将被OS清理之前(这里的清理,系统会保存当前activity的一些堆栈信息,用于下回重启activity),系统会调用 protected void onSaveInstanceState(Bundle outState) {} 我们就在这里去通过反射把所有的filds[]去输出的outState,下次启动时,在Oncreate()中判断 protected void onCreate(Bundle savedInstanceState) {}, savedInstanceState是不是空,如果是空说明是正常的Activity跳转,如果不空说明是异常关闭activity后,ANDROID OS 重新启动的一个“新activity”,此时调用在BaseActivity()中写好的一个loadData()
以下摘自: http://blog.csdn.net/liuwenbo0920/article/details/7290586
java   @interface Annotation{ }  定义一个注解 @Annotation,一个注解是一个类。
@Override@Deprecated@SuppressWarnings 为常见的3个注解。
注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,
JAVAC 编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事。
   注解 @Override 用在方法上,当我们想重写一个方法时,在方法上加 @Override ,当我们方法的名字出错时,编译器就会报错,如图:

        注解 @Deprecated ,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法
上用 @Deprecated 修饰,如图:
   注解 @SuppressWarnings 用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,如图:
注解 @Retention 可以用来修饰注解,是注解的注解,称为元注解。
Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy3个值: CLASS    RUNTIME     SOURCE @Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;
@Retention(RetentionPolicy.SOURCE ) 修饰的注解 , 表示注解的信息会被编译器抛弃,不会留在 class 文件中,注解的信息只会留在源文件中;
@Retention(RetentionPolicy.RUNTIME ) 修饰的注解,表示注解的信息被保留在 class 文件 ( 字节码文件 ) 中当程序编译时,会被虚拟机保留在运行时,

所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.

1.package com.self;  
2.import java.lang.annotation.Retention;  
3.import java.lang.annotation.RetentionPolicy;  
4.  
5.@Retention(RetentionPolicy.RUNTIME)  
6.public @interface MyTarget  
7.{ }  
8.定义个一注解@MyTarget,用RetentionPolicy.RUNTIME修饰;  
9.package com.self;  
10.import java.lang.reflect.Method;  
11.public class MyTargetTest  
12.{  
13. @MyTarget  
14. public void doSomething()  
15. {  
16.  System.out.println("hello world");  
17. }  
18.   
19. public static void main(String[] args) throws Exception  
20. {  
21.  Method method = MyTargetTest.class.getMethod("doSomething",null);  
22.  if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在注解@MyTarget,则为true  
23.  {  
24.   System.out.println(method.getAnnotation(MyTarget.class));  
25.  }  
26.  }  
27.}  
28.上面程序打印:@com.self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印。  
29.  
30. @Retention(RetentionPolicy.SOURCE )  
31.public @interface Override  
32.  
33.@Retention(RetentionPolicy.SOURCE )  
34.public @interface SuppressWarnings  
35.  
36.@Retention(RetentionPolicy.RUNTIME )  
37.public @interface Deprecated  
38.由上可以看出,只有注解@Deprecated在运行时可以被JVM读取到  
39.  
40.注解中可以定义属性,看例子:  
41.@Retention(RetentionPolicy.RUNTIME)  
42.public @interface MyAnnotation  
43.{  
44. String hello() default "gege";  
45.  String world();  
46.  int[] array() default { 2, 4, 5, 6 };  
47.  EnumTest.TrafficLamp lamp() ;  
48.  TestAnnotation lannotation() default @TestAnnotation(value = "ddd");  
49.  Class style() default String.class;  
50.}  
51.上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为:  
52.hello,world,array,lamp,lannotation,style.  
53.属性hello类型为String,默认值为gege  
54.属性world类型为String,没有默认值  
55.属性array类型为数组,默认值为2,4,5,6  
56.属性lamp类型为一个枚举,没有默认值  
57.属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解  
58.属性style类型为Class,默认值为String类型的Class类型  
59.  
60.看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值  
61.@MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)  
62.public class MyTest  
63.{  
64. @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW)  
65. @Deprecated  
66. @SuppressWarnings("")  
67. public void output()  
68. {  
69.  System.out.println("output something!");  
70. }  
71.}  
72. 接着通过反射读取注解的信息:  
73.public class MyReflection  
74.{  
75. public static void main(String[] args) throws Exception  
76. {  
77.  MyTest myTest = new MyTest();  
78.    Class c = MyTest.class;  
79.    Method method = c.getMethod("output", new Class[] {});  
80.       //如果MyTest类名上有注解@MyAnnotation修饰,则为true  
81.  if(MyTest.class.isAnnotationPresent(MyAnnotation.class))  
82.  {  
83.   System.out.println("have annotation");  
84.  }  
85.   if (method.isAnnotationPresent(MyAnnotation.class))  
86.   {  
87.   method.invoke(myTest, null); //调用output方法  
88.   //获取方法上注解@MyAnnotation的信息  
89.     MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);  
90.    String hello = myAnnotation.hello();  
91.   String world = myAnnotation.world();  
92.   System.out.println(hello + ", " + world);//打印属性hello和world的值  
93.   System.out.println(myAnnotation.array().length);//打印属性array数组的长度  
94.   System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值  
95.   System.out.println(myAnnotation.style());  
96.   }  
97.    //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的  
98.     Annotation[] annotations = method.getAnnotations();  
99.      for (Annotation annotation : annotations)  
100.  {  
101.   System.out.println(annotation.annotationType().getName());  
102.  }  
103.   }  
104.}  
105.上面程序打印:  
106.have annotation  
107.output something!  
108.gege, shanghai  
109.3  
110.baby  
111.class java.lang.String  
112.com.heima.annotation.MyAnnotation  
113.java.lang.Deprecated  
114.  
115.如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。  
116.可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,  
117.属性的返回类型是RetentionPolicy,如下:  
118.public @interface MyTarget  
119.{  
120.    String value();  
121.}  
122.可以这样用:  
123.  @MyTarget("aaa")  
124. public void doSomething()  
125. {  
126.  System.out.println("hello world");  
127. }  
128.   
129.注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型,  
130.值为:ANNOTATION_TYPE CONSTRUCTOR  FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE  
131.如@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上。  
132.@Target(ElementType.METHOD)  
133.@Retention(RetentionPolicy.RUNTIME)  
134.public @interface MyTarget  
135.{  
136. String value() default "hahaha";  
137.}  
138.如把@MyTarget修饰在类上,则程序报错,如:  
139.@MyTarget  
140.public class MyTargetTest  
注解大都用在开发框架中吧,好了有关注解就学习那么多了,谢谢。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值