设为首页 加入收藏

TOP

自己动手写事件总线(EventBus)(二)
2019-09-01 23:26:29 】 浏览:106
Tags:自己 手写 事件 总线 EventBus
e eventType = new EventType(paramType); SubscriberMethod subscriberMethod = new SubscriberMethod(method, annotation.threadMode(), paramType); realSubscribe(subscriber, subscriberMethod, eventType); } } } clazz = clazz.getSuperclass(); } } ... private void realSubscribe(Object subscriber, SubscriberMethod method, EventType eventType) { CopyOnWriteArrayList<Subscription> subscriptions = mSubscriptionsByEventtype.get(subscriber); if (subscriptions == null) { subscriptions = new CopyOnWriteArrayList<>(); } Subscription subscription = new Subscription(subscriber, method); if (subscriptions.contains(subscription)) { return; } subscriptions.add(subscription); mSubscriptionsByEventtype.put(eventType, subscriptions); } ... }

执行过这些逻辑后,该对象所有的观察者方法都会被存在一个Map中,其Key是EventType,即观察事件的类型,Value是订阅了该类型事件的所有方法(即观察者)的一个列表,每个方法和对象一起封装成了一个Subscription类:


public class Subscription {

    public final Reference<Object> subscriber;

    public final SubscriberMethod subscriberMethod;

    public Subscription(Object subscriber, 

                        SubscriberMethod subscriberMethod) {

        this.subscriber = new WeakReference<>(subscriber);// EventBus3 没用弱引用?

        this.subscriberMethod = subscriberMethod;

    }

    @Override

    public int hashCode() {

        return subscriber.hashCode() + subscriberMethod.methodString.hashCode();

    }

    @Override

    public boolean equals(Object obj) {

        if (obj instanceof Subscription) {

            Subscription other = (Subscription) obj;

            return subscriber == other.subscribe

                    && subscriberMethod.equals(other.subscriberMethod);

        } else {

            return false;

        }

    }

}

如此,便是注册监听方法的核心逻辑了。

消息发送

消息的发送代码很简单:


public class EventBus {

    ...

    private EventDispatcher mEventDispatcher = new EventDispatcher();

    private ThreadLocal<Queue<EventType>> mThreadLocalEvents = new ThreadLocal<Queue<EventType>>() {

        @Override

        protected Queue<EventType> initialValue() {

            return new ConcurrentLinkedQueue<>();

        }

    };

    ...

    public void post(Object message) {

        if (message == null) {

            return;

        }

        mThreadLocalEvents.get().offer(new EventType(message.getClass()));

        mEventDispatcher.dispatchEvents(message);

    }

    ...

}

比较复杂一点的是需要根据注解声明的线程模式在对应的线程进行发布:


public class EventBus {

    ...

    private class EventDispatcher {

        private IEventHandler mMainEventHandler = new MainEventHandler();

        private IEventHandler mPostEventHandler = new DefaultEventHandler();

        private IEventHandler mAsyncEventHandler = new AsyncEventHandler();

        void dispatchEvents(Object message) {

            Queue<EventType> eventQueue = mThreadLocalEvents.get();

            while (eventQueue.size() > 0) {

                handleEvent(eventQueue.poll(), message);

            }

        }

        private void handleEvent(EventType eventType, Object message) {

            List<Subscription> subscriptions = mSubscriptionsByEventtype.get(eventType);

            if (subscriptions == null) {

                return;

            }

            for (Subscription subscription : subscriptions) {

                IEventHandler eventHandler =  getEventHandler(subscription.subscriberMethod.threadMode);

                eventHandler.handleEvent(subscription, message);

            }

        }

        private IEventHandler getEventHandler(ThreadMode mode) {

            if (mode == ThreadMode.ASYNC) {

                return mAsyncEventHandler;

            }

            if (mode == ThreadMode.POST) {

首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android 彩色Toast实现 下一篇findlibrary returned null

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目