EventBus框架分析&实现

EventBus使用详解及组件之间通信中我们已经介绍了EventBus的使用及注册,接受消息,销毁等流程,下面我们就分析一下EventBus是如何实现


 
注册
 
     
Eventbus.getDefault().register(this);
发送消息
Eventbus.getDefault().post(new MessageBean("meg", "test"));
接收消息
@Subscribe(threadMode = ThreadMode.Async)
public void receive(MessageBean messageBean ) {
}

 
实现思路:


 (1).定义注解 Subscribe

@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
    ThreadMode threadMode() default ThreadMode.PostThread;
}
(2).注册Activity

register
 

private static Eventbus instance = new Eventbus();

private ExecutorService executorService;
//存放对应的activity及 线程类型,接受参数,及对应的方法
private Map<Object, List<SubscribleMethod>> cacheMap;

private Handler handler;
public static Eventbus getDefault() {
    return instance;
}

private Eventbus( ) {
    this.cacheMap = new HashMap<>();
    executorService = Executors.newCachedThreadPool();
    handler = new Handler(Looper.getMainLooper());
}



/** * 注册 * @param activity */ public void register(Object activity) { Class<?> clazz = activity.getClass(); List<SubscribleMethod> list = cacheMap.get(activity);// 如果已经注册 就不需要注册 if (list == null) { list = getSubscribleMethods(activity); cacheMap.put(activity, list); } }



/**
 * 寻找能够接受事件的方法
 *
 * @param activity
 * @return
 */
private List<SubscribleMethod> getSubscribleMethods(Object activity) {
    List<SubscribleMethod> list = new ArrayList<>();
    Class clazz = activity.getClass();
    /**
     * BaseActivity   ---->Activity(找 )
     */
    while (clazz != null) {

        String name = clazz.getName();
        if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
            break;
        }
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            Subscribe subscribe = method.getAnnotation(Subscribe.class);
            if (subscribe == null) {
                continue;
            }

            Class[] paratems = method.getParameterTypes();
            if (paratems.length != 1) {
                throw new RuntimeException("eventbus只能接收到一个参数");
            }
            //
            ThreadMode threadMode = subscribe.threadMode();
            SubscribleMethod subscribleMethod = new SubscribleMethod(method
                    , threadMode, paratems[0]);
            list.add(subscribleMethod);

        }
        clazz = clazz.getSuperclass();
    }

    return list;

}


(3).接受消息

@Subscribe(threadMode = ThreadMode.Async)
public void receive(MessageBean messageBean ) {
}
(4).发送消息

 /**
     * 通知
     * @param msg
     */
    public void post(final Object msg) {
        /**
         * 遍历 找到 注册的activity
         */
        Set<Object> set = cacheMap.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            final Object activity = iterator.next();
            List<SubscribleMethod> list = cacheMap.get(activity);
            for (final SubscribleMethod subscribleMethod : list) {
//                判断 这个方法是否应该接受事件
                if (subscribleMethod.getEventType().isAssignableFrom(msg.getClass())) {
                    switch (subscribleMethod.getThreadMode()) {
//                        接受方法在子线程执行的情况
                        case Async:
                            if (Looper.myLooper() == Looper.getMainLooper()) {
//                                post方法  执行在子线程
                                executorService.execute(new Runnable() {
                                    @Override
                                    public void run() {
                                        invoke(subscribleMethod, activity, msg);
                                    }
                                });

                            } else {
//                                post方法  执行在子线程

                                invoke(subscribleMethod, activity, msg);
                            }
                            break;
                        //                        接受方法在主线程执行的情况
                        case MainThread:
                            if (Looper.myLooper() == Looper.getMainLooper()) {
//                                需要  1  不需要2
                                invoke(subscribleMethod, activity, msg);
                            } else {
//                                post方法  执行在子线程     接受消息 在主线程
                                handler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        invoke(subscribleMethod, activity, msg);
                                    }
                                });
                            }
                            break;
                        case PostThread:
                            break;
                            default:
                                break;
                    }
                }
            }
        }
    }



/**
*调用activity
@Subscribe(threadMode = ThreadMode.Async)
public void receive(MessageBean messageBean ) /
private void invoke(SubscribleMethod subscribleMethod, Object activity, Object mesg) { Method method = subscribleMethod.getMethod(); try { method.invoke(activity, mesg); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }}


注:isAssignableFrom

Determines if the class or interface represented by this
* {@code Class} object is either the same as, or is a superclass or
* superinterface of, the class or interface represented by the specified
* {@code Class} parameter. It returns {@code true} if so;
* otherwise it returns {@code false}. If this {@code Class}
* object represents a primitive type, this method returns
* {@code true} if the specified {@code Class} parameter is
* exactly this {@code Class} object; otherwise it returns
* {@code false}.
大概意思:
确定由这个@code Class对象所表示的类或接口是否与指定的@code Class参数所表示的类或接口相同,或者是超类或超接口。
如果是这样,它返回@code true;否则它会返回@code false。如果这个@code Class对象代表一个原始类型,那么如果指定的@code Class参数恰好是@code Class对象,
那么这个方法将返回@code true;否则它会返回@code false
class1.isAssignableFrom(class2) 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true;否则返回 false。如果该 Class 表示一个基本类型,且指定的 Class 参数正是该 Class 对象,则该方法返回 true;否则返回 false1.class2是不是class1的子类或者子接口

        2.Object是所有类的父类



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值