注解是一种很优雅的书写方式,也是我们的代码变的简洁,更加快捷方便编写代码。下面以绑定onclick实践为例阐述注解的原理。
BaseEvent用来制定需要绑定的方法名,事件的Listener,和绑定执行的方法名,BaseEvent的代码如下
思路:可以通过我们的注解对象中取得添加onclick注解的方法(testUpload)反射方法对象,对这个对象进行事件的绑定。动态代理View事件中的OnclickLister,向代理对象中添加方法对象(testUpload)。方法的添加在EventListenerManager管理类中完成。
EventLisernerManager中定义动态代理类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public static void addEventMethod(Method method, Annotation annotation, Object value, Object handler, ViewFinder finder){ try { View view = finder.findViewByInfo(value); if (view!= null ){ BaseEvent baseEvent = annotation.annotationType().getAnnotation(BaseEvent. class ); Class<!--?--> listenerType = baseEvent.listenerType(); String listenerSetter = baseEvent.listenerSetter(); String methodName = baseEvent.methodName(); Object listener = listenerCache.get(value, listenerType); boolean addMethod = false ; DynamicHandler dymicHandler = null ; if (listener!= null ){ dymicHandler = (DynamicHandler) Proxy.getInvocationHandler(listener); addMethod = (handler.equals(dymicHandler.getHandler())); if (addMethod){ dymicHandler.addMethod(methodName, method); } } if (!addMethod){ dymicHandler = new DynamicHandler(handler); dymicHandler.addMethod(methodName, method); listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class<!--?-->[]{listenerType},dymicHandler); listenerCache.put(value, listenerType, listener); } //setListener Method setterMethod = view.getClass().getMethod(listenerSetter, listenerType); setterMethod.invoke(view, listener); } } catch (Exception e){ LogUtils.e(e.getMessage(),e); } } |
解析注解添加方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | Method[] methods = handlerType.getDeclaredMethods(); if (methods.length> 0 ){ for (Method method:methods){ Annotation[] annotations = method.getDeclaredAnnotations(); for (Annotation annotation : annotations){ Class<!--?--> anType = annotation.annotationType(); //拿到Annotation的Class if (anType.getAnnotation(BaseEvent. class )!= null ){ method.setAccessible( true ); try { Method valueMethod = anType.getDeclaredMethod( "values" ); Object values = valueMethod.invoke(annotation); int len = Array.getLength(values); if (len> 0 ){ for ( int i= 0 ;i<len;i++){ object= "" value= "Array.get(values," i);= "" eventlistenermanager.addeventmethod(method,= "" annotation,= "" value,= "" handlertype,= "" finder);= "" }= "" } catch (exception= "" e){= "" e.printstacktrace();= "" }<= "" pre= "" > 这里可以拿到自定义method和注解本身。不太了解的可以研究下java的annotation的用法。<p></p> <p>由以上的方法的可以实现注解事件的绑定,可以自己定义事件的注解,优雅的开始你的代码吧!</p> <p><br> </p> <p><br> </p> <p><br> <br> </p> <br> <p><br> </p> <p><br> <br> </p> <br> <p><br> </p> </len;i++){> |
联系客服