(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
注解反射动态代理实现控件事件注入
1.实现思路
(1)定义事件类型注解, 其属性值包含事件监听类,与监听事件方法名称。
(2)定义单击事件注解,其属性值为单击事件控件的id数组集合。
(3)定义单击长按事件注解,其属性值为单击长按事件控件的id数组集合。
(4)定义事件注解解析器,通过反射获取方法上所有的注解信息,解析注解信息获取监听事件的数据类型及设置监听事件的方法名称。
(5)通过动态代理生成事件监听注入的代理类对象,通过反射获取监听事件需要执行的方法并执行。
2.定义事件类型注解
@Target({ ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface EventType {
//注解属性,监听类
Class listenerType();
//注解属性,监听事件方法名称
String listenerSetter();
}
3.定义单击,单击长按事件注解
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@EventType(listenerType = View.OnClickListener.class,listenerSetter = "setOnClickListener")
public @interface OnClick{
int[] value();
}
@Target({ ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@EventType(listenerType = View.OnLongClickListener.class,listenerSetter = "setOnLongClickListener")
public @interface OnLongClick {
int[] value();
}
4.定义注解信息解析器
public class InjectUtils {
/**
* 利用反射、注解、动态代理为指定Activity类的控件注入事件
*/
public static void injectEvent(Activity activity){
Class<? extends Activity> activityClass = activity.getClass();
Method[] declaredMethods = activityClass.getDeclaredMethods();
for(Method method : declaredMethods){
//1.获取方法上所有的注解信息
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation : annotations){
//1.1解析注解信息
Class<? extends Annotation> annotationType =
annotation.annotationType();
//1.2方法返回true,如果指定类型的注解存在于此元素上,否则返回false。
if(annotationType.isAnnotationPresent(EventType.class)){
//1.2.1获取注解类信息
EventType eventType =
annotationType.getAnnotation(EventType.class);
//1.2.2获取监听事件类型
Class listenerType = eventType.listenerType();
//1.2.3获取设置监听事件的方法名称
String listenerSetter = eventType.listenerSetter();
try {
//1.2.4取得控件id
Method valueMethod = annotationType.getDeclaredMethod("value");
int[] viewIds = (int[]) valueMethod.invoke(annotation);
//1.2.5通过动态代理动态生成事件处理对象
method.setAccessible(true);
ListenerInvocationHandler<Activity> handler =
new ListenerInvocationHandler<>(activity,method);
Object listenerProxy =
Proxy.newProxyInstance(listenerType.getClassLoader(),
new Class[]{listenerType},handler);
for(int viewId : viewIds){
//1.2.6.获取需要添加事件的控件
View view = activity.findViewById(viewId);
//1.2.7通过反射获取监听事件
Method setter =
view.getClass().getMethod(listenerSetter,listenerType);
setter.invoke(view,listenerProxy);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 事件回调之所以使用泛型T,是因为控件类型有可能是自定义的View.
* @param <T>
*/
static class ListenerInvocationHandler<T> implements InvocationHandler{
private Method method;
private T target;
public ListenerInvocationHandler(T target,Method method) {
this.method = method;
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//解决Expected to unbox a 'boolean' primitive type but was returned null异常
if (boolean.class == method.getReturnType()) {
this.method.invoke(target, objects);
return true;
}else {
return this.method.invoke(target, objects);
}
}
}
}
5.使用
/**
* 通过注解、反射、依赖注入实现控件事件的自动注入
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.injectEvent(this);
}
@OnClick({R.id.btn1,R.id.btn2})
public void click(View view){
switch (view.getId()){
case R.id.btn1:
Log.i(TAG,"click:按钮1");
break;
case R.id.btn2:
Log.i(TAG,"click:按钮2");
break;
}
}
@OnLongClick({R.id.btn1,R.id.btn2})
public void longClick(View view){
switch (view.getId()){
case R.id.btn1:
Log.i(TAG,"longClick:按钮1");
break;
case R.id.btn2:
Log.i(TAG,"longClick:按钮2");
break;
}
}
}
6.打赏鼓励
感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!