您当前的位置: 首页 >  android

xiangzhihong8

暂无认证

  • 1浏览

    0关注

    1324博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

android EventBus详解(三)

xiangzhihong8 发布时间:2016-02-25 11:23:45 ,浏览量:1

post()方法调用流程

我们继续来看EventBus类,的另一个入口方法post()

//已省略部分代码
public void post(Object event) {
    PostingThreadState postingState = currentPostingThreadState.get();
    List eventQueue = postingState.eventQueue;
    eventQueue.add(event);

    if (!postingState.isPosting) {
        postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper();
        postingState.isPosting = true;
        if (postingState.canceled) {
            throw new EventBusException("Internal error. Abort state was not reset");
        }
        while (!eventQueue.isEmpty()) {
            postSingleEvent(eventQueue.remove(0), postingState);
        }
        postingState.isPosting = false;
        postingState.isMainThread = false;
    }
}

post() 方法首先从 currentPostingThreadState 对象中取了一个 PostingThreadState ,我们来看看这个 currentPostingThreadState 对象的创建代码。

private final ThreadLocal currentPostingThreadState = new
ThreadLocal() {
    @Override
    protected PostingThreadState initialValue() {
        return new PostingThreadState();
    }
};

ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,而这段数据是不会与其他线程共享的。其内部原理是通过生成一个它包裹的泛型对象的数组,在不同的线程会有不同的数组索引值,通过这样就可以做到每个线程通过 get() 方法获取的时候,取到的只能是自己线程所对应的数据。  在 EventBus 中, ThreadLocal 所包裹的是一个 PostingThreadState 类,它仅仅是封装了一些事件发送中过程所需的数据。

final static class PostingThreadState {
    //通过post方法参数传入的事件集合
    final List eventQueue = new ArrayList(); 
    boolean isPosting; //是否正在执行postSingleEvent()方法
    boolean isMainThread;
    Subscription subscription;
    Object event;
    boolean canceled;
    }

回到 post() 方法,我们看到其核心代码是这句:

while (!eventQueue.isEmpty()) {
    postSingleEvent(eventQueue.remove(0), postingState);
}

每次调用post()的时候都会传入一个事件,这个事件会被加入到队列。而每次执行postSingleEvent()都会从队列中取出一个事件,这样不停循环取出事件处理,直到队列全部取完。  再看 postSingleEvent() 方法

private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
    Class eventClass = event.getClass();
    boolean subscriptionFound = false;
    if (eventInheritance) {
        //获取到eventClass所有父类的集合
        List clazz = eventTypes.get(h);
            //左或右只要有一个为真则为真,并赋值给左
            subscriptionFound |= postSingleEventForEventType(event, postingState, clazz);
        }
    } else {
        subscriptionFound = postSingleEventForEventType(event, postingState, eventClass);
    }
    if (!subscriptionFound) {
        if (logNoSubscriberMessages) {
            Log.d(TAG, "No subscribers registered for event " + eventClass);
        }

        //参考sendNoSubscriberEvent注释
        if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
                eventClass != SubscriberExceptionEvent.class) {
            post(new NoSubscriberEvent(this, event));
        }
    }
}

还记得 EventBusBuild 中的 eventInheritance是做什么的吗?它表示一个子类事件能否响应父类的onEvent() 方法。 再往下看 lookupAllEventTypes() 它通过循环和递归一起用,将一个类的父类,接口,父类的接口,父类接口的父类,全部添加到全局静态变量 eventTypes 集合中。之所以用全局静态变量的好处在于用全局静态变量只需要将那耗时又复杂的循环+递归方法执行一次就够了,下次只需要通过 key:事件类名 来判断这个事件是否以及执行过 lookupAllEventTypes() 方法。

postSingleEventForEventType()方法

然后我们继续往下,看发送方法 postSingleEventForEventType()

private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class eventClass) {
    CopyOnWriteArrayList subscriptions;
    synchronized (this) {
        //所有订阅了eventClass的事件集合
        subscriptions = subscriptionsByEventType.get(eventClass);
    }
    if (subscriptions != null && !subscriptions.isEmpty()) {
        //回调subscription的响应方法
        for (Subscription subscription : subscriptions) {
            postingState.event = event;
            postingState.subscription = subscription;
            boolean aborted = false;
            try {
                postToSubscription(subscription, event, postingState.isMainThread);
                aborted = postingState.canceled;
            } finally {
                postingState.event = null;
                postingState.subscription = null;
                postingState.canceled = false;
            }
            if (aborted) {
                break;
            }
        }
        return true;
    }
    return false;
}

它首先通过这一句

subscriptions = subscriptionsByEventType.get(eventClass);

获取到所有订阅了 eventClass 的事件集合,之前有讲过, subscriptionsByEventType 是一个以 key:订阅的事件 value:订阅这个事件的所有订阅者集合 的 Map 。 最后通过循环,遍历所有订阅了 eventClass 事件的订阅者,并向每一个订阅者发送事件。 看它的发送事件的方法: postToSubscription(subscription, event, postingState.isMainThread);  噢,又回到了和之前 Subscribe 流程中处理粘滞事件相同的方法里————对声明不同线程模式的事件做不同的响应方法,最终都是通过invokeSubscriber()反射订阅者类中的以onEvent开头的方法。

unregister()

我们继续来看EventBus类,的最后一个入口方法unregister()

public synchronized void unregister(Object subscriber) {
    List            
关注
打赏
1482932726
查看更多评论
0.1529s