首先创建一个项目:
这个项目很简单,就三个类,一个activity,一个注解,一个注解工具类,首先看一下activity中的代码:
package com.gefufeng.annotationdemo; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { @ViewInject(value = R.id.text,defaultText = "你好注解") private TextView text; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InjectUtils.init(this); } }
这个activity非常简单,就是为了演示annotation用的,其中有一个Textview,id为R.id.text,然后我为它加上了一个自定义注解Viewinject,下面看一下这个注解:
package com.gefufeng.annotationdemo; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ViewInject { int value(); String defaultText(); }
这个注解中我先简单的介绍一下几个名词:
1.@interface : 加上它ViewInject就表示一个自定义的注解
2.@Target :表示这个注解是给谁用的,是一个类的,还是一个方法呢,还是一个变量呢,等等
3.@Retention:这个注解的生命周期,有的注解在原文件中有效,有的在class文件中还有效,有的在运行时还有效
4.@Ducumented:Documented是一个标记注解,没有成员,用于描述其它类型的annotation应该被作为被标注的程序成员的公共API
OK,注解中有两个方法,就是声明了两个参数,方法的名称就是参数的名称。
下面看一下InjectUtils类:
package com.gefufeng.annotationdemo; import java.lang.reflect.Field; import android.app.Activity; import android.view.View; import android.widget.TextView; public class InjectUtils { public static void init(Activity ac){ Class<?> c = ac.getClass(); Field[] fields = c.getDeclaredFields(); for (Field f : fields) { ViewInject viewInject = f.getAnnotation(ViewInject.class); if (viewInject != null) { int id = viewInject.value(); String defaultText = viewInject.defaultText(); View view = ac.findViewById(id); if (view instanceof TextView) { ((TextView)view).setText(defaultText); } f.setAccessible(true); try { f.set(ac, view); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
这个类也比较简单,就一个静态的init方法,用于在activity中初始化。
首先找出activity中公开的变量,然后遍历这些变量,查找哪些变量有ViewInject注解,如果有,取出value和defaultText的值,最后调用f.set(ac, view);对于field.set()方法,源码中的解释为:
Sets the value of the field in the specified object to the value. This reproduces the effect of {@code object.fieldName = value}
OK,一个注解初始化view的例子到此完成,运行这个android程序,这个textview就已被初始化,默认值为“你好注解”。
关于注解的知识这里没做系统的介绍,只是在android演示了怎么使用注解