使用 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, 才搞清楚, 唉,功力不够。
现在项目的代码就用到了这个库,做了一些简单的封装。
最近工作中发现了自己的一个认识误区:以前一直以为如果是在和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, 才搞清楚, 唉,功力不够。
相关文章推荐
- [转载]从 VC7 的 CHtmlView 不能正常退出谈 CComPtr 使用中的一个误区
- Android中一个Activity调用另一个Activity — Intent对象的使用
- Android NDK rb5 文档之使用 Android 工具链作为一个独立编译器
- 使用android ProgressBar和Toast生成一个界面
- android 不同Activity使用一个SharedPreference
- EditPlus+JDK使用中的一个误区。
- 从 VC7 的 CHtmlView 不能正常退出谈 CComPtr 使用中的一个误区
- Android游戏引擎《Rokon》学习笔记六:一个使用Box2D的Rokon小例子:Rokon Donate
- 推荐:MAX函数和GROUP BY 语句一起使用的一个误区
- Android中自定义属性的使用------res/values文件下定义一个attrs.xml
- Android:一个Activity想使用Content Provider中的数据
- 从 VC7 的 CHtmlView 不能正常退出谈 CComPtr 使用中的一个误区
- android同一个程序中使用多个地图出现混乱怎么办?!
- android上使用cocos2dx的一个bug
- 从 VC7 的 CHtmlView 不能正常退出谈 CComPtr 使用中的一个误区
- Android SDK开发指南(翻译)系列三:Tools(一)--使用AIDL, 设计一个远程接口
- android同一个程序中使用多个地图出现混乱怎么办?!
- android同一个程序中使用多个地图出现混乱怎么办?!
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三)