Android annotation (annotation) to bind events
Annotation is a very elegant way of writing. It is also a simple and convenient way to write code. The following describes how to bind an onclick annotation.
1. Define The Onclick annotation class
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@BaseEvent(listenerSetter = "setOnclickListener", listenerType = View.OnClickListener.class, methodName = "onclick")public @interface OnClick { int[] values();}
BaseEvent is used to specify the name of the method to be bound, the Listener of the event, and the name of the method to be bound. The BaseEvent code is as follows:
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface BaseEvent {Class
listenerType();String listenerSetter();String methodName();}
2. Custom annotation usage
@OnClick(R.id.download_btn) public void testUpload(View view) {}
3. Analysis of annotations (Key Points ):
Idea: You can use our annotation object to obtain the Reflection Method object for adding the onclick annotation (testUpload), and bind the event to this object. The OnclickLister in the dynamic proxy View event adds the method object (testUpload) to the proxy object ). The method is added to the EventListenerManager management class.
EventLisernerManager defines the dynamic proxy class:
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);}//setListenerMethod setterMethod = view.getClass().getMethod(listenerSetter, listenerType);setterMethod.invoke(view, listener);}}catch(Exception e){LogUtils.e(e.getMessage(),e);}}
Listener = Proxy. newProxyInstance (listenerType. getClassLoader (), new Class [] {ListenerType}, dymicHandler); dynamically proxies onClickListener. Class to cache proxy objects:
// Cache proxy object public final static DoubleKeyValueMap
, Object> listenerCache = null;
Resolution annotation addition method:
Method [] methods = handlerType. getDeclaredMethods (); if (methods. length> 0) {for (Method method: methods) {Annotation [] annotations = method. getDeclaredAnnotations (); for (Annotation annotation: annotations) {Class
AnType = annotation. annotationType (); // get Annotation's Classif (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
Here we can get the custom method and annotation itself. I don't know much about java's annotation usage.
The above method can bind annotation events, and you can define the annotation of events by yourself. Let's start your code elegantly!