kotlin使用注解遇到的问题

今天自己学者写个注解框架,参考butterknife,在实现点击事件的时候遇到一个问题。

java代码:

Class<?> clazz = object.getClass();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                Class<? extends Annotation> annotationType = annotation.annotationType();
                InjectEvent injectEvent = annotationType.getAnnotation(InjectEvent.class);

                String listenerSetter = injectEvent.listenerSetter();
                Class<?> listenerType = injectEvent.listenerType();
                String callBackMethod = injectEvent.callBackMethod();

                try {
                    Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(),
                            new Class[]{listenerType}, new ListenerHandler(object, method));

                    Method valueMethod = annotationType.getDeclaredMethod("value");
                    int[] ids = (int[]) valueMethod.invoke(annotation);

                    for (int id : ids) {

                        Method findViewById = clazz.getMethod("findViewById", int.class);
                        View view = (View) findViewById.invoke(object, id);

                        Method setterMethod = view.getClass().getMethod(listenerSetter, listenerType);
                        setterMethod.invoke(view, listener);
                    }

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

直接用转换工具转换:

嗯?啥情况。

翻看源码得知,kotlin是通过 annotationClass 来获取 annotationType 的

so,改成了这样~

// 事件注入
    private fun injectEvent(obj: Any) {

        val clazz = obj.javaClass
        // 获取所有方法
        val methods = clazz.declaredMethods
        methods.forEach { method ->
            // 获取方法上的所有注解
            val annot = method.annotations
            annot.forEach { annotation ->
                // 根据annotationType获取injectEvent
                val annotationType = annotation.annotationClass.java
                val injectEvent = annotationType.getAnnotation(InjectEvent::class.java)
                injectEvent?.let {
                    
                    //  获取传递的参数
                    val listenerSetter = it.listenerSetter
                    val listenerType = it.listenerType.java
                    val callBackMethod = it.callBackMethod

                    // 动态代理注入要执行的方法(onClilc还是onLongClick或者其他的)
                    val listener = Proxy.newProxyInstance(
                        listenerType.classLoader,
                        arrayOf(listenerType),
                        ListenerHandler(obj, method)
                    )
                    
                    // 获取注解的value方法并获取其值
                    val valueMethod = annotationType.getDeclaredMethod("value")
                    val ids = valueMethod.invoke(annotation) as IntArray

                    //遍历id获取具体的控件,并为其设置相应的触摸事件
                    ids.forEach { mId ->
                        val findViewById = clazz.getMethod("findViewById", Int::class.java)
                        val view = findViewById.invoke(obj, mId) as View

                        val setterMethod = view.javaClass.getMethod(listenerSetter, listenerType)
                        setterMethod.invoke(view, listener)
                    }
                }

            }
        }

    }
搞定~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值