Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android注解(annotation)實現綁定事件的原理

Android注解(annotation)實現綁定事件的原理

編輯:關於Android編程

注解是一種很優雅的書寫方式,也是我們的代碼變的簡潔,更加快捷方便編寫代碼。下面以綁定onclick實踐為例闡述注解的原理。

1、定義Onclick注解類

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@BaseEvent(listenerSetter = "setOnclickListener", 
           listenerType = View.OnClickListener.class, 
           methodName = "onclick")
public @interface OnClick {
     int[] values();
}

BaseEvent用來制定需要綁定的方法名,事件的Listener,和綁定執行的方法名,BaseEvent的代碼如下

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BaseEvent {
	Class listenerType();
	String listenerSetter();
	String methodName();
}

2、自定義的注解使用方式

 @OnClick(R.id.download_btn)
 public void testUpload(View view) {}

3、注解的解析(重點):

思路:可以通過我們的注解對象中取得添加onclick注解的方法(testUpload)反射方法對象,對這個對象進行事件的綁定。動態代理View事件中的OnclickLister,向代理對象中添加方法對象(testUpload)。方法的添加在EventListenerManager管理類中完成。

EventLisernerManager中定義動態代理類:

	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);
		}
	}
listener = Proxy.newProxyInstance(listenerType.getClassLoader(),new Class[]{listenerType},dymicHandler);動態的代理了onClickListener。類中對代理對象進行的緩存:

//緩存代理對象
public final static DoubleKeyValueMap, Object> listenerCache = null;


解析注解添加方法:

		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        這裡可以拿到自定義method和注解本身。不太了解的可以研究下java的annotation的用法。

由以上的方法的可以實現注解事件的綁定,可以自己定義事件的注解,優雅的開始你的代碼吧!











  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved