注解、反射、范型实现注解工具类

1.setContentView绑定

  //注解

/**
 * Created by dell on 2018/1/24.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Inherited
public @interface ContentView {
    int value();
}

2.实现控件绑定

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

3.实现控件的点击事件绑定

   //注解的应用注释

public @interface EventControl {

    /**
     * 设置事件监听的方法
     * @return
     */
    String listenerMethod();

    /**
     * 设置事件回调的方法
     * @return
     */
    String callBack();

    /**
     * 获取监听类型
     * @return
     */
    Class<?> getClazzType();
}
//注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
@EventControl(
        listenerMethod = "setOnClickListener",
        callBack = "onClick",
        getClazzType = View.OnClickListener.class)
public @interface OnClick {
    int[] value();//对一组数据添加监听
}
//注解工具类
public class InjectUtil {

    /**
     * 注入activity,作用是通过反射,运行相关逻辑
     * @param activity
     */
    public static void inject(Activity activity){
         inJectContentView(activity);
         inJectViews(activity);
         inOnclick(activity);
}

    private static void inOnclick(final Activity activity) {
        Method[] methods = activity.getClass().getMethods();
        for (Method method : methods) {
            //1.获取方法上的所有注解
            Annotation[] annotations = method.getAnnotations();
            //2判断注解是否是我们需要的注解:也就是注解上是否包含event
            for (Annotation annotation : annotations) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                //获取注解上是否有我们约定好的注解
                EventControl eventControl = annotationType.getAnnotation(EventControl.class);
                if (eventControl == null) {
                    //说明不是我们想要的注解,跳出此次循环
                    continue;
                }
                //获取注解上声明好的内容
                String listener = eventControl.listenerMethod();
                String callback = eventControl.callBack();//要拦截的方法
                Class<?> listenerType = eventControl.getClazzType();

                final Map<String, Method> methodMap = new HashMap<>();

                methodMap.put(callback, method);

                try {
                    Method valueMethod = annotationType.getDeclaredMethod("value");
                    //第一个参数是接受者,也就是这里的注解对象,也就是调用annotation的value方法,如果后面有参数
                    //则在后面声明不定参数
                    int[] viewIds = (int[]) valueMethod.invoke(annotation);

                    //遍历id找到view
                    for (int viewId : viewIds) {
                        final View view = activity.findViewById(viewId);
                        if (view != null) {
                            //给view添加监听
                            if (view == null) {
                                continue;
                            }
                            //获取设置监听的方法,但是不知道对什么设置监听:onClick,onItemClick...
                            Method setListenerMethod = view.getClass().getMethod(listener, listenerType);
                            //这里只有listener的类型
                            //根据对应类型生成对应的代理类对象
                            Object proxyInstance = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class[]{listenerType}, new InvocationHandler() {
                                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                                    if (methodMap != null) {
                                        //获取对应方法在map中是否存在,这里的是我们的handle方法
                                        Method m = methodMap.get(method.getName());
                                        if (m != null) {
                                            //调用存入map中的方法,也就是我们在activity中声明监听注解的方法
                                            return m.invoke(activity, args);
                                        }
                                    }
                                    return method.invoke(proxy, args);
                                }
                            });
                            //给view设置监听
                            setListenerMethod.invoke(view, proxyInstance);
                        }
                    }
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    private static void inJectViews(Activity activity) {
        //得到Activity字节码
        Class clazz= activity.getClass();
        //得到activity的所以成员变量
        Field[] fields = clazz.getDeclaredFields();
         if(fields!=null&&fields.length>0){
             for (Field field:fields) {
                 //设置权限
                 field.setAccessible(true);
                 //得到成员变量上面的注解
                 BindView bindView = field.getAnnotation(BindView.class);
                 if(bindView!=null){
                     //得到成员变量的值
                     int id = bindView.value();
                     Log.e("BindVIEW",id+"ASDASD");
                     //得到每个id的view
                     View view = activity.findViewById(id);
                     try {
                         //通过反射的方法初始化成员变量
                         field.set(activity,view);
                     } catch (IllegalAccessException e) {
                         e.printStackTrace();
                     }
                 }
             }
         }
    }

    private static void inJectContentView(Activity activity) {
        //得到Activity字节码
        Class clazz = activity.getClass();
        //得到类上面的注解
       ContentView contentView = (ContentView) clazz.getAnnotation(ContentView.class);
        if(contentView!=null){
            int layoutID = contentView.value();
            try {
                //获取方法
                Method method = clazz.getMethod("setContentView",int.class);
                //给方法赋值
                method.invoke(activity,layoutID);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }



    }
}

//mainActivity
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity{
    @BindView(R.id.name_tv)
    Button tv;
    @BindView(R.id.btn)
    Button btn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        InjectUtil.inject(this);
        tv.setText("男  难  南 楠  囡");
    }

    @OnClick(R.id.name_tv)
    public void b1(View v){
        Toast.makeText(this,"成功1",Toast.LENGTH_SHORT).show();
    }
    @OnClick(R.id.btn)
    public void b2(View v){
        Toast.makeText(this,"男  难  南 楠  囡",Toast.LENGTH_SHORT).show();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值