反射方法
getClass() 获取类
getAnnotation() 获取注解
getMethod() 获取方法 (包括父类 所有public方法)
invoke() 执行方法
getDeclaredMethod() 获取所有方法(当前类的所有方法,包括private等)
getDeclaredFields() 获取所有属性
annotationType() 获取注解的类型
一、绑定布局
1、首先创建一个Library Module依赖在项目
2、在Library 创建一个InjectManager类,类里创建一个inject方法,方法里面分别调用3个方法,如图:
首先了解 injectLayout(activity)这个方法,实现 @ContentView(R.layout.activity_main)注解替换setContentView(R.layout.activity_main)方法,如图:
接下来如何实现呢?
1、在Library 创建一个注解类,如图:
上图@Target注解,是作用在(方法,类,接口等等)之上,ElementType有几种不同的作用:
1)ElementType.ANNOTATION_TYPE : 是元注解,作用在注解的注解之上
2)ElementType.TYPE : 作用在 (类,接口) 之上
3)ElementType.METHOD : 作用在 方法 之上
4)ElementType.FIELD : 作用在 属性枚举 之上
5)ElementType.PACKAGE : 作用在 包 之上
@Retention注解,RetentionPolicy有几种不同的作用:
1)RetentionPolicy.RUNTIME :jvm运行时通过反射获取该注解的值
2)RetentionPolicy.CLASS : 作用在 检查 方面操作
3)RetentionPolicy.SOURCE :在原文件中有效,被编译器丢弃。
注意:上图中的 int value(); 表示布局中R.layout.activity_main是int值
2、在InjectManager的injectLayout(activity)方法通过反射实现注解绑定,如图:
3、在MainActivity中代码检测是否实现了,如果吐司了,说明成功了
二、绑定控件ID
1、在Library创建InjectView注解类,如图
2、在InjectManager的injectView(activity)方法通过反射实现注解绑定,如图:
注意:如果field.setAccessible(true)没有添加这句,而且当前属性为private,运行起来会出现闪退
三、注解绑定点击事件
1、在Library创建EventBase注解类,如图:
1)listenerSetter()方法相当于控件点击事件的setOnClickListener方法
2)listenerType()方法相当于控件点击事件的View.OnClickListener()或者View.OnLongClickListener()方法
3)callBackListener()方法相当于控件点击事件的onClick()或者onLongClick()回调方法
2、在Library创建OnClick注解类,如图:
1)图中@EventBase(listenerSetter = “setOnClickListener”,listenerType = View.OnClickListener.class, callBackListener = “onClick”)这句是作用在OnClick注解之上(注解的注解之上)
2)这个int[] value()方法位数组,因为在注解中可能有多个ID值:如:@OnClick({R.id.text,R.id.btn})
3、在InjectManager的injectEvents(activity)方法通过反射实现注解绑定,如图:
注意:上面两张图是一个方法
下面就是代理的原理和用法
最后:拦截下来的方法是通过setter.invoke(view,listener);实现自己自定义的方法
3、在MainActivity中点击事件代码,如图:
结束了…
demo链接:https://gitee.com/JenKinLi/ReflexDemo.git