Android- 创建一个简单的事件订阅组件(一)


 Android- 创建一个简单的事件订阅组件(一)

 

  介绍  

          本文将基于反射与注解来介绍如何创建一个简单的事件订阅组件.

    概述

       本文中使用到的注解

           1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明                 的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。

    2. @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果                         Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。

            3.@Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME。

      1.既然使用到了注解,那么我们首先创建一个注解类

@Documented
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@Target({ElementType.METHOD}) //只使用在方法上
public @interface Register {

}

2.创建注册与解绑

     //注册
      EventHelper.getInstance().register(this);
     //解绑
      EventHelper.getInstance().unregister(this);

3.既然是事件订阅。那么我们需支持所有的类。包括但不限于(Activity,Fragment,View,自定义类);那么发送的类型为object类型

          
      EventHelper.getInstance().postEvent(new User("你大爷"));



至此 外层调用方法结束。接下来我们实现内部逻辑.

首先开始注册方法register() ,对注册的类必须进行校验来保证事件订阅的成功。如果成功情况下存进map。

public void register(Object object) {
   Class<?> aClass = object.getClass();
 //加入前先校验是否有注解了方法
   checkHasMethod(aClass);
   classHashMap.put(object.hashCode(), object);

   }

   

       该方法对传进来的类进行了方法校验及注解校验.这里的获取方法不推荐getDeclaredMethods(),而是推荐使用公共参数来减少遍历层。




 
 
/**
     * 校验类方法名
     *
     * @param aClass
     */
    private void checkHasMethod(Class<?> aClass) {
        Method[] methods = aClass.getMethods();
        boolean has_on_event = false;
        int j = 0;
        for (int i = 0; i < methods.length; i++) {
            String name = methods[i].getName();
            Log.i(TAG, "checkHasMethod name:" + name);
            if (name.equals("onEvent")) {
                has_on_event = true;
                j = i;
                break;
            } else {
                has_on_event = false;
            }
        }
        if (!has_on_event) {
            throw new EventException("注册的类里没有onEvent方法或非公共参数");
        }
        Register annotation = methods[j].getAnnotation(Register.class); //检测注解
        if (annotation == null) {
            throw new EventException("注册的onEvent方法未使用Register注解");
        }

    }
对于解绑操作。我们只要将map里对应的实例移除即可;


post方法

   public synchronized void postEvent(Object event) {
        //向所有注册的类发送事件
        for (Map.Entry<Integer, Object> entry : classHashMap.entrySet()) {
            Object value = entry.getValue();
            Class aClass = value.getClass();
            try {
                //
                Method[] methods = aClass.getMethods();
                for (int i = 0; i < methods.length; i++) {
                    Method method = methods[i];
                    if (method.getName().equals("onEvent")) {
                        method.invoke(value, event);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }



public void unregister(Object object) {
       classHashMap.remove(object.hashCode());
}	


至此整个事件订阅完成,我们来简单的测试一下 MainActivity 创建onEvent方法并使用@Register注解

二级页面也创建一个

发送事件


2个页面成功接收到了参数。

以上只是对注解进行了简单的使用。还能有更复杂的用法及更简便的配置

@Documented
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@Target({ElementType.METHOD}) //只使用在方法上
public @interface Register {
         String value();
}
使用注解来配置所接收的事件;简化流程;

当然以上的简易Demo 对于 多方法还是不支持的。

如何支持,及使用注解来简化流程,下一章节分晓。(待更。)

github源码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值