自定义注解

来源:互联网 发布:小非农数据公布网站 编辑:程序博客网 时间:2024/06/05 20:40

前言

今天来看看自定义注解

实例一

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitColor {    enum Color{        RED,BLUE,GREEN    }//    方法的名称就是参数的名称,返回值类型就是参数的值类型    Color fruitColor() default Color.BLUE;}
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitName {     String value() default "apple";}
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface FruitProvider {    int id()  default -1;    String name() default "";    String address() default "";}
public class Apple {    @FruitName("Orange")    private String appleName;    @FruitColor(fruitColor = FruitColor.Color.GREEN)    private String appleColor;    @FruitProvider(id=2,name="zhangsan",address = "北京")    private String appleProvider;    public void setAppleName(String appleName){        this.appleName = appleName;    }    public String getAppleName(){        return appleName;    }    public void setAppleColor(String appleColor){        this.appleColor = appleColor;    }    public String getAppleColor(){        return appleColor;    }    public void setAppleProvider(String appleProvider){        this.appleProvider = appleProvider;    }    public String getAppleProvider(){        return appleProvider;    }}
public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);    }    public void click(View view) {        FruitInfoUtil.getFruitInfo(Apple.class);    }}

运行结果

System.out: ====水果颜色GREENSystem.out: =====水果名称OrangeSystem.out: ===水果供应商:2--zhangsan--北京

实例二
自定义ViewMapping代替setContentView,

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ViewMapping {    int value();}
public class ViewUtil {//    传入的Activity    private static Class<?> activityClass;    public static void inject(Object obj) {        activityClass = obj.getClass();        injectContentView(obj);    }    private static void injectContentView(Object obj){        //判断类上是否有注解        if (activityClass.isAnnotationPresent(ViewMapping.class)) {            // 获取注解对象            ViewMapping viewMapping = activityClass.getAnnotation(ViewMapping.class);            //布局文件的id            int layoutId = viewMapping.value();                //获取方法对象,第二个参数是可变的,代表方法需要的参数类型            try {                Method setContentView = activityClass.getMethod("setContentView", int.class);                //执行方法,第一个参数是执行方法的对象,第二个是方法传入的参数的值                setContentView.invoke(obj,layoutId);            } catch (Exception e) {                e.printStackTrace();            }        }    }}

使用

@ViewMapping(R.layout.main)public class MainActivity extends Activity {    private static final String TAG = "MainActivity";    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ViewUtil.inject(this);    }}

实例三
自定义注解代替fintViewById

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface FindViewById {    int value();}
  private static void injectViewId(Object obj){//       获取所有的属性,不包括继承的        Field[] fields = activityClass.getDeclaredFields();        for (Field field:fields) {//            判断字段是否有注解            if (field.isAnnotationPresent(FindViewById.class)) {                //获取注解的值                int viewId = field.getAnnotation(FindViewById.class).value();                try {                    Method findViewById = activityClass.getMethod("findViewById", int.class);//                    获取findViewById方法的返回值                    Object viewValue = findViewById.invoke(obj, viewId);                    if (Modifier.PUBLIC != field.getModifiers()) {                        //给字段赋值前,要保证字段是可访问的                        field.setAccessible(true);                    }                    //为字段赋值                    field.set(obj,viewValue);                } catch (Exception e) {                    e.printStackTrace();                }            }        }    }

实例四
自定义注解代替点击事件

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface OnClick {    //因为可能有多个控件需要点击事件,所以这里的返回值就是一个int数组    int[] value();}
 private static void injectClickListener(Object obj){        Method[] methods = activityClass.getMethods();        for (Method method : methods) {            //如果方法上存在OnClick的注解            if (method.isAnnotationPresent(OnClick.class)) {                //获取方法上的注解                OnClick onClick = method.getAnnotation(OnClick.class);                int[] viewIds = onClick.value();                //代理处理类                MInvocationhandler invocationhandler = new MInvocationhandler(obj,method);                Object proxyInstance = Proxy.newProxyInstance(View.OnClickListener.class.getClassLoader(), new Class<?>[]{View.OnClickListener.class}, invocationhandler);                //遍历所有控件id,设置代理                for (int i : viewIds) {                    try {                        Object view = activityClass.getMethod("findViewById", int.class).invoke(obj, i);                        if (view != null) {                            Method clickListener = view.getClass().getMethod("setOnClickListener", View.OnClickListener.class);                            clickListener.invoke(view,proxyInstance);                        }                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }    }    private static class MInvocationhandler implements InvocationHandler {        private Object object;        private Method  method;        public MInvocationhandler(Object object,Method method){            this.object= object;            this.method = method;        }        @Override        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {            return this.method.invoke(object,args);        }    }
原创粉丝点击