您的位置:首页 > 移动开发 > Android开发

使用 android EventBus的一个误区

2014-10-20 21:53 253 查看
EvenBus是一个广为使用的android开源库,用来作为事件通知和触发响应,集合了观察者模式和命令模式,可以很好的扩展以及解耦,是很好用的android库。

现在项目的代码就用到了这个库,做了一些简单的封装。

最近工作中发现了自己的一个认识误区:以前一直以为如果是在和eventBus同一个线程post一个event, 那么一定会同步的执行注册了此event的所有响应,

不过在实践中却发现并非如此:

EventBus中对于投递一个event在同一个线程的情况,在进行投递时,会首先判断一个threadLocal变量,看当前线程是否正在投递(isPosting变量标示),触发注册此event的响应, 如果isPosting, 那么就直接将此event object放入到 ThreadLocal的一个queue, 然后直接返回, 如果不是isPosting, 那么会从event queue中依次取出所有的没有被投递的event,进行相应的投递响应.

从这里看,明显的,绝对不是一个同步的操作,

而我遇到的场景是这样的:

<1> event1被触发(EventBus.post(event1)), 然后开始执行其响应 A(),

<2> 而在A()里面会触发event2(EventBus.post(event2)),而event2()也会开始投递到其响应函数B(),

<3> 但是因为isPosting, 因此将event2放入此线程的eventBus queue, 然后直接返回.

<4> A()执行完了, event1的投递响应到此结束,

<5>虽然event1的投递已经完成, 但是event queue的队列又多了一个event2(之前放入的),那么开始处理event2的响应,执行B().

从这个过程就可以看到,执行链条是这样的: event1 -> A() begin -> event2 ->A() end -> B() begin -> B() end.

而我一开始认为的是 event1 -> A() begin -> event2 -> B() begin - > B() end -> A() end.

绝对不是一个同步执行返回的结果,这样认为会导致很多的时序性问题。

一开始分析的时候,看log,没想到A()还会触发EventBus.Post, 还以为是多线程,后来打了threadId,发现是同一个线程,差点以为出bug了,后来关键点打了下stackTrace, 才搞清楚, 唉,功力不够。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: