android源码、开源框架解析

Android学习之动态代理+注解+反射实现点击事件注入

2021-08-13  本文已影响0人  青草黄了

1、实现效果

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //事件注入
        EventInject.injectUtils(this);
    }
    
    //onClick注解实现点击事件注入
    @onClick({R.id.testid,R.id.testid1})
    public void onclick(View view){
        switch (view.getId()){
            case R.id.testid:
                Toast.makeText(this,"testid",Toast.LENGTH_LONG).show();
                break;
            case R.id.testid1:
                Toast.makeText(this,"testid1",Toast.LENGTH_LONG).show();
                break;
        }
    }
    //onLongClick注解实现长按事件注入
    @onLongClick({R.id.testid,R.id.testid1})
    public boolean onLongclick(View view){
        switch (view.getId()){
            case R.id.testid:
                Toast.makeText(this,"testid onlongclick",Toast.LENGTH_LONG).show();
                break;
            case R.id.testid1:
                Toast.makeText(this,"testid1 onlongclick",Toast.LENGTH_LONG).show();
                break;
        }
        return false;
    }

2、具体实现

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface EventType {
    Class listenerType();
    String listenerSetter();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@EventType(listenerType = View.OnClickListener.class,listenerSetter = "setOnClickListener")
@interface onClick {
    int[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@EventType(listenerType = View.OnLongClickListener.class,listenerSetter = "setOnLongClickListener")
@interface onLongClick {
    int[] value();
}

注入工具类

public static void injectUtils(Activity activity){
        Class<? extends Activity> activityClass = activity.getClass();
        Method[] methods = activityClass.getMethods();
        //遍历Activity上所有方法
        for (Method method : methods) {
            Annotation[] methodAnnotations = method.getAnnotations();
            //遍历方法上所有注解
            for (Annotation methodAnnotation : methodAnnotations) {
                Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
                if (annotationType.isAnnotationPresent(EventType.class)){
                    EventType eventType = annotationType.getAnnotation(EventType.class);
                    Class listenerType = eventType.listenerType();
                    String listenerSetter = eventType.listenerSetter();

                    try {
                        Method valuemethod = annotationType.getDeclaredMethod("value");
                        int[] ids = (int[]) valuemethod.invoke(methodAnnotation);

                        EventInvocationHandler<Activity> handler = new EventInvocationHandler<>(method,activity);
                        Object proxyInstance = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class[]{listenerType}, handler);

                        for (int id : ids) {
                            View view = activity.findViewById(id);

                            Method methodSettet = view.getClass().getMethod(listenerSetter,listenerType);
                            methodSettet.setAccessible(true);
                            methodSettet.invoke(view,proxyInstance);


                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }


                }
            }

        }
    }

    static class EventInvocationHandler<T> implements InvocationHandler{

        Method method;
        T t;

        public EventInvocationHandler(Method method, T t) {
            this.method = method;
            this.t = t;
        }

        @Override
        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
            return method.invoke(t,args);
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读